"""
Ecosystem file mapping.
Maps project/config files between language ecosystems so that
non-code files (package manifests, build configs, etc.) are also
converted to their equivalent in the target ecosystem.

Also identifies "priority files" (constants, configs, types) that
should be converted first and used as context for other files.
"""
import os

# Ecosystem file mappings: source_filename -> target_filename
# Keyed by (source_lang_group, target_lang_group)
# A "lang group" collapses similar ecosystems (e.g., JS/TS share Node).
ECOSYSTEM_MAP = {
    # Python -> Node.js (JavaScript / TypeScript)
    ("python", "node"): {
        "requirements.txt":    "package.json",
        "setup.py":            "package.json",
        "setup.cfg":           "package.json",
        "pyproject.toml":      "package.json",
        "Pipfile":             "package.json",
        "Makefile":            "package.json",
        ".flake8":             ".eslintrc.json",
        ".pylintrc":           ".eslintrc.json",
        "mypy.ini":            "tsconfig.json",
        "pytest.ini":          "jest.config.js",
        "tox.ini":             "jest.config.js",
        ".python-version":     ".nvmrc",
        "Dockerfile":          "Dockerfile",
    },
    # Node.js -> Python
    ("node", "python"): {
        "package.json":        "requirements.txt",
        "tsconfig.json":       "mypy.ini",
        ".eslintrc.json":      ".flake8",
        ".eslintrc.js":        ".flake8",
        ".eslintrc.yml":       ".flake8",
        "jest.config.js":      "pytest.ini",
        "jest.config.ts":      "pytest.ini",
        ".nvmrc":              ".python-version",
        ".node-version":       ".python-version",
        "Dockerfile":          "Dockerfile",
    },
    # Python -> Java / Kotlin
    ("python", "jvm"): {
        "requirements.txt":    "build.gradle",
        "setup.py":            "build.gradle",
        "pyproject.toml":      "build.gradle",
        "Makefile":            "build.gradle",
        "pytest.ini":          "build.gradle",
        "Dockerfile":          "Dockerfile",
    },
    # Java / Kotlin -> Python
    ("jvm", "python"): {
        "pom.xml":             "requirements.txt",
        "build.gradle":        "requirements.txt",
        "build.gradle.kts":    "requirements.txt",
        "settings.gradle":     "pyproject.toml",
        "settings.gradle.kts": "pyproject.toml",
        "Dockerfile":          "Dockerfile",
    },
    # Python -> Go
    ("python", "go"): {
        "requirements.txt":    "go.mod",
        "setup.py":            "go.mod",
        "pyproject.toml":      "go.mod",
        "Makefile":            "Makefile",
        "Dockerfile":          "Dockerfile",
    },
    # Go -> Python
    ("go", "python"): {
        "go.mod":              "requirements.txt",
        "go.sum":              "requirements.txt",
        "Makefile":            "Makefile",
        "Dockerfile":          "Dockerfile",
    },
    # Python -> Rust
    ("python", "rust"): {
        "requirements.txt":    "Cargo.toml",
        "setup.py":            "Cargo.toml",
        "pyproject.toml":      "Cargo.toml",
        "Makefile":            "Cargo.toml",
        "Dockerfile":          "Dockerfile",
    },
    # Rust -> Python
    ("rust", "python"): {
        "Cargo.toml":          "requirements.txt",
        "Cargo.lock":          "requirements.txt",
        "Dockerfile":          "Dockerfile",
    },
    # Node.js -> Java / Kotlin
    ("node", "jvm"): {
        "package.json":        "build.gradle",
        "tsconfig.json":       "build.gradle",
        "jest.config.js":      "build.gradle",
        "Dockerfile":          "Dockerfile",
    },
    # Java / Kotlin -> Node.js
    ("jvm", "node"): {
        "pom.xml":             "package.json",
        "build.gradle":        "package.json",
        "build.gradle.kts":    "package.json",
        "Dockerfile":          "Dockerfile",
    },
    # C# -> Node.js
    ("dotnet", "node"): {
        "*.csproj":            "package.json",
        "*.sln":               "package.json",
        "Dockerfile":          "Dockerfile",
    },
    # Node.js -> C#
    ("node", "dotnet"): {
        "package.json":        "Project.csproj",
        "tsconfig.json":       "Project.csproj",
        "Dockerfile":          "Dockerfile",
    },
    # Ruby -> Python
    ("ruby", "python"): {
        "Gemfile":             "requirements.txt",
        "Rakefile":            "Makefile",
        "Dockerfile":          "Dockerfile",
    },
    # Python -> Ruby
    ("python", "ruby"): {
        "requirements.txt":    "Gemfile",
        "Makefile":            "Rakefile",
        "Dockerfile":          "Dockerfile",
    },
}

# Map language names to ecosystem groups
_LANG_TO_GROUP = {
    "Python":       "python",
    "JavaScript":   "node",
    "TypeScript":   "node",
    "CoffeeScript": "node",
    "Java":         "jvm",
    "Kotlin":       "jvm",
    "Scala":        "jvm",
    "Groovy":       "jvm",
    "Go":           "go",
    "Rust":         "rust",
    "C#":           "dotnet",
    "F#":           "dotnet",
    "VB.NET":       "dotnet",
    "Ruby":         "ruby",
    "PHP":          "php",
    "Swift":        "apple",
    "Objective-C":  "apple",
    "Dart":         "dart",
    "Elixir":       "beam",
    "Erlang":       "beam",
}


def get_lang_group(lang_name: str) -> str:
    """Get the ecosystem group for a language."""
    return _LANG_TO_GROUP.get(lang_name, lang_name.lower())


def get_ecosystem_mappings(source_lang: str, target_lang: str) -> dict:
    """
    Get the ecosystem file mappings for a source→target pair.
    Returns dict of {source_filename: target_filename}.
    """
    src_group = get_lang_group(source_lang)
    tgt_group = get_lang_group(target_lang)
    return ECOSYSTEM_MAP.get((src_group, tgt_group), {})


# --- Priority files: converted first, used as context for others ---

# Patterns that indicate a file contains constants, types, or configuration
# that other files are likely to depend on. Sorted by priority (highest first).
PRIORITY_PATTERNS = [
    # Type definitions / interfaces
    "types", "interfaces", "models", "schema", "entities",
    # Constants and configuration
    "constants", "config", "settings", "enums", "enum",
    # Shared utilities
    "utils", "helpers", "common", "shared", "base",
    # Package / module init
    "__init__", "index", "mod", "lib", "main",
]


def classify_priority(filepath: str) -> int:
    """
    Return a priority score for a file (lower = higher priority).
    Files matching priority patterns get scores 0..N.
    Non-matching files get score 1000.
    """
    basename = os.path.splitext(os.path.basename(filepath))[0].lower()
    for idx, pattern in enumerate(PRIORITY_PATTERNS):
        if pattern in basename:
            return idx
    return 1000


def sort_files_by_priority(filepaths: list[str]) -> list[str]:
    """Sort files so that priority files come first."""
    return sorted(filepaths, key=classify_priority)


def get_priority_files(filepaths: list[str], max_context_files: int = 5) -> list[str]:
    """
    Return the top N priority files that should be converted first
    and used as context for other files.
    """
    sorted_files = sort_files_by_priority(filepaths)
    priority = []
    for f in sorted_files:
        if classify_priority(f) < 1000:
            priority.append(f)
            if len(priority) >= max_context_files:
                break
    return priority
