#!/bin/bash
#
# Design System Server (DSS) - Project Discovery Script
#
# Non-intrusive analysis of project structure, dependencies, and health.
# Outputs JSON for UI consumption.
#
# Usage: ./discover.sh [project_path] [--full]
#

set -e

PROJECT_PATH="${1:-.}"
FULL_SCAN="${2:-}"
OUTPUT_DIR="${PROJECT_PATH}/.dss"
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")

# Create output directory
mkdir -p "$OUTPUT_DIR"

# Colors for terminal output (only if interactive)
if [ -t 1 ]; then
  GREEN='\033[0;32m'
  BLUE='\033[0;34m'
  YELLOW='\033[1;33m'
  NC='\033[0m'
else
  GREEN=''
  BLUE=''
  YELLOW=''
  NC=''
fi

log() {
  echo -e "${BLUE}[DSS]${NC} $1" >&2
}

# === Project Type Detection ===

detect_project_type() {
  local types=()

  [ -f "$PROJECT_PATH/package.json" ] && types+=("nodejs")
  [ -f "$PROJECT_PATH/requirements.txt" ] || [ -f "$PROJECT_PATH/pyproject.toml" ] && types+=("python")
  [ -f "$PROJECT_PATH/Cargo.toml" ] && types+=("rust")
  [ -f "$PROJECT_PATH/go.mod" ] && types+=("go")
  [ -f "$PROJECT_PATH/pom.xml" ] || [ -f "$PROJECT_PATH/build.gradle" ] && types+=("java")
  [ -f "$PROJECT_PATH/Gemfile" ] && types+=("ruby")
  [ -f "$PROJECT_PATH/composer.json" ] && types+=("php")

  echo "${types[@]:-unknown}"
}

# === Framework Detection ===

detect_frameworks() {
  local frameworks=()

  if [ -f "$PROJECT_PATH/package.json" ]; then
    local pkg=$(cat "$PROJECT_PATH/package.json")

    echo "$pkg" | grep -q '"react"' && frameworks+=("react")
    echo "$pkg" | grep -q '"vue"' && frameworks+=("vue")
    echo "$pkg" | grep -q '"@angular/core"' && frameworks+=("angular")
    echo "$pkg" | grep -q '"svelte"' && frameworks+=("svelte")
    echo "$pkg" | grep -q '"next"' && frameworks+=("nextjs")
    echo "$pkg" | grep -q '"nuxt"' && frameworks+=("nuxt")
    echo "$pkg" | grep -q '"express"' && frameworks+=("express")
    echo "$pkg" | grep -q '"fastify"' && frameworks+=("fastify")
    echo "$pkg" | grep -q '"tailwindcss"' && frameworks+=("tailwind")
    echo "$pkg" | grep -q '"@emotion"' && frameworks+=("emotion")
    echo "$pkg" | grep -q '"styled-components"' && frameworks+=("styled-components")
  fi

  if [ -f "$PROJECT_PATH/requirements.txt" ]; then
    grep -q "fastapi" "$PROJECT_PATH/requirements.txt" && frameworks+=("fastapi")
    grep -q "django" "$PROJECT_PATH/requirements.txt" && frameworks+=("django")
    grep -q "flask" "$PROJECT_PATH/requirements.txt" && frameworks+=("flask")
  fi

  echo "${frameworks[@]:-none}"
}

# === Design System Detection ===

detect_design_system() {
  local ds_info='{"detected":false}'

  # Check for common design system indicators
  if [ -f "$PROJECT_PATH/package.json" ]; then
    local pkg=$(cat "$PROJECT_PATH/package.json")

    if echo "$pkg" | grep -qE '"(@chakra-ui|@mui|antd|@radix-ui|@headlessui)"'; then
      ds_info='{"detected":true,"type":"library"}'
    fi
  fi

  # Check for custom design tokens
  if find "$PROJECT_PATH" -maxdepth 3 -name "tokens.css" -o -name "tokens.json" -o -name "design-tokens.*" 2>/dev/null | grep -q .; then
    ds_info='{"detected":true,"type":"custom","has_tokens":true}'
  fi

  # Check for Figma integration
  if find "$PROJECT_PATH" -maxdepth 3 -name ".figmarc" -o -name "figma.config.*" 2>/dev/null | grep -q .; then
    ds_info=$(echo "$ds_info" | sed 's/}$/,"figma_connected":true}/')
  fi

  echo "$ds_info"
}

# === File Statistics ===

get_file_stats() {
  local total_files=$(find "$PROJECT_PATH" -type f ! -path "*/node_modules/*" ! -path "*/.git/*" ! -path "*/dist/*" ! -path "*/__pycache__/*" 2>/dev/null | wc -l)
  local js_files=$(find "$PROJECT_PATH" -type f \( -name "*.js" -o -name "*.jsx" -o -name "*.ts" -o -name "*.tsx" \) ! -path "*/node_modules/*" 2>/dev/null | wc -l)
  local css_files=$(find "$PROJECT_PATH" -type f \( -name "*.css" -o -name "*.scss" -o -name "*.less" \) ! -path "*/node_modules/*" 2>/dev/null | wc -l)
  local py_files=$(find "$PROJECT_PATH" -type f -name "*.py" ! -path "*/__pycache__/*" 2>/dev/null | wc -l)
  local component_files=$(find "$PROJECT_PATH" -type f \( -name "*.jsx" -o -name "*.tsx" -o -name "*.vue" -o -name "*.svelte" \) ! -path "*/node_modules/*" 2>/dev/null | wc -l)

  cat <<EOF
{
  "total": $total_files,
  "javascript": $js_files,
  "css": $css_files,
  "python": $py_files,
  "components": $component_files
}
EOF
}

# === Dependency Analysis ===

analyze_dependencies() {
  local deps='{"production":[],"development":[],"total":0}'

  if [ -f "$PROJECT_PATH/package.json" ]; then
    local prod_count=$(jq '.dependencies | length // 0' "$PROJECT_PATH/package.json" 2>/dev/null || echo 0)
    local dev_count=$(jq '.devDependencies | length // 0' "$PROJECT_PATH/package.json" 2>/dev/null || echo 0)
    local total=$((prod_count + dev_count))

    deps="{\"production\":$prod_count,\"development\":$dev_count,\"total\":$total}"
  fi

  if [ -f "$PROJECT_PATH/requirements.txt" ]; then
    local py_deps=$(grep -v "^#" "$PROJECT_PATH/requirements.txt" | grep -v "^$" | wc -l)
    deps="{\"python\":$py_deps,\"total\":$py_deps}"
  fi

  echo "$deps"
}

# === Git Analysis ===

analyze_git() {
  if [ ! -d "$PROJECT_PATH/.git" ]; then
    echo '{"is_repo":false}'
    return
  fi

  cd "$PROJECT_PATH"

  local branch=$(git branch --show-current 2>/dev/null || echo "unknown")
  local commits=$(git rev-list --count HEAD 2>/dev/null || echo 0)
  local contributors=$(git log --format='%ae' | sort -u | wc -l 2>/dev/null || echo 0)
  local last_commit=$(git log -1 --format='%ci' 2>/dev/null || echo "unknown")
  local uncommitted=$(git status --porcelain 2>/dev/null | wc -l || echo 0)

  cat <<EOF
{
  "is_repo": true,
  "branch": "$branch",
  "commits": $commits,
  "contributors": $contributors,
  "last_commit": "$last_commit",
  "uncommitted_changes": $uncommitted
}
EOF
}

# === Component Discovery ===

discover_components() {
  local components=()

  # Find component files
  while IFS= read -r file; do
    if [ -n "$file" ]; then
      local name=$(basename "$file" | sed 's/\.[^.]*$//')
      local dir=$(dirname "$file" | sed "s|^$PROJECT_PATH/||")
      components+=("{\"name\":\"$name\",\"path\":\"$dir\",\"file\":\"$(basename "$file")\"}")
    fi
  done < <(find "$PROJECT_PATH" -type f \( -name "*.jsx" -o -name "*.tsx" -o -name "*.vue" \) ! -path "*/node_modules/*" ! -path "*/.next/*" ! -path "*/dist/*" 2>/dev/null | head -50)

  # Join array
  local joined=$(IFS=,; echo "${components[*]}")
  echo "[$joined]"
}

# === Health Score ===

calculate_health_score() {
  local score=100
  local issues=()

  # Check for package-lock or yarn.lock
  if [ -f "$PROJECT_PATH/package.json" ]; then
    if [ ! -f "$PROJECT_PATH/package-lock.json" ] && [ ! -f "$PROJECT_PATH/yarn.lock" ] && [ ! -f "$PROJECT_PATH/pnpm-lock.yaml" ]; then
      score=$((score - 10))
      issues+=("\"No lock file found\"")
    fi
  fi

  # Check for .gitignore
  if [ -d "$PROJECT_PATH/.git" ] && [ ! -f "$PROJECT_PATH/.gitignore" ]; then
    score=$((score - 5))
    issues+=("\"Missing .gitignore\"")
  fi

  # Check for README
  if [ ! -f "$PROJECT_PATH/README.md" ] && [ ! -f "$PROJECT_PATH/README" ]; then
    score=$((score - 5))
    issues+=("\"Missing README\"")
  fi

  # Check for tests
  if ! find "$PROJECT_PATH" -maxdepth 3 -type d \( -name "test" -o -name "tests" -o -name "__tests__" -o -name "spec" \) 2>/dev/null | grep -q .; then
    score=$((score - 10))
    issues+=("\"No test directory found\"")
  fi

  # Check for TypeScript
  if [ -f "$PROJECT_PATH/package.json" ] && ! [ -f "$PROJECT_PATH/tsconfig.json" ]; then
    if grep -q "typescript" "$PROJECT_PATH/package.json" 2>/dev/null; then
      score=$((score - 5))
      issues+=("\"TypeScript installed but no tsconfig.json\"")
    fi
  fi

  local joined_issues=$(IFS=,; echo "${issues[*]}")

  cat <<EOF
{
  "score": $score,
  "grade": "$([ $score -ge 90 ] && echo 'A' || ([ $score -ge 80 ] && echo 'B' || ([ $score -ge 70 ] && echo 'C' || ([ $score -ge 60 ] && echo 'D' || echo 'F'))))",
  "issues": [$joined_issues]
}
EOF
}

# === CSS Analysis ===

analyze_css() {
  local css_files=$(find "$PROJECT_PATH" -type f \( -name "*.css" -o -name "*.scss" \) ! -path "*/node_modules/*" 2>/dev/null)
  local total_files=$(echo "$css_files" | grep -c . || echo 0)

  local has_variables=false
  local has_custom_properties=false
  local preprocessor="none"

  if echo "$css_files" | grep -q ".scss"; then
    preprocessor="sass"
  fi

  if [ -n "$css_files" ]; then
    for file in $css_files; do
      if grep -q -- "--" "$file" 2>/dev/null; then
        has_custom_properties=true
      fi
      if grep -q "\\\$" "$file" 2>/dev/null; then
        has_variables=true
      fi
    done
  fi

  cat <<EOF
{
  "files": $total_files,
  "preprocessor": "$preprocessor",
  "has_css_variables": $has_custom_properties,
  "has_preprocessor_variables": $has_variables
}
EOF
}

# === Main Discovery ===

log "Starting project discovery..."

PROJECT_TYPES=$(detect_project_type)
FRAMEWORKS=$(detect_frameworks)
DESIGN_SYSTEM=$(detect_design_system)
FILE_STATS=$(get_file_stats)
DEPENDENCIES=$(analyze_dependencies)
GIT_INFO=$(analyze_git)
HEALTH=$(calculate_health_score)
CSS_INFO=$(analyze_css)

if [ "$FULL_SCAN" = "--full" ]; then
  COMPONENTS=$(discover_components)
else
  COMPONENTS="[]"
fi

# Build final JSON
cat > "$OUTPUT_DIR/discovery.json" <<EOF
{
  "meta": {
    "version": "1.0.0",
    "timestamp": "$TIMESTAMP",
    "project_path": "$PROJECT_PATH",
    "full_scan": $([ "$FULL_SCAN" = "--full" ] && echo true || echo false)
  },
  "project": {
    "types": $(echo "$PROJECT_TYPES" | jq -R 'split(" ")' 2>/dev/null || echo '["unknown"]'),
    "frameworks": $(echo "$FRAMEWORKS" | jq -R 'split(" ")' 2>/dev/null || echo '[]')
  },
  "design_system": $DESIGN_SYSTEM,
  "files": $FILE_STATS,
  "dependencies": $DEPENDENCIES,
  "git": $GIT_INFO,
  "health": $HEALTH,
  "css": $CSS_INFO,
  "components": $COMPONENTS
}
EOF

log "Discovery complete: $OUTPUT_DIR/discovery.json"

# Output the JSON
cat "$OUTPUT_DIR/discovery.json"
