import click
import subprocess
import shutil
import platform
import os
import sys
from pathlib import Path
from .config_parser import CppProjectConfig

@click.group()
def cli():
    pass

def _setup_global_command():
    system = platform.system()

    if system == "Windows":
        bin_dir = Path(os.environ.get('LOCALAPPDATA', os.path.expanduser('~\\AppData\\Local'))) / 'IncludeCPP' / 'bin'
        bin_dir.mkdir(parents=True, exist_ok=True)

        script_path = bin_dir / 'includecpp.bat'
        with open(script_path, 'w') as f:
            f.write('@echo off\n')
            f.write(f'"{sys.executable}" -m includecpp %*\n')

        current_path = os.environ.get('PATH', '')
        bin_dir_str = str(bin_dir)

        if bin_dir_str not in current_path:
            try:
                import winreg
                key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, 'Environment', 0, winreg.KEY_ALL_ACCESS)
                try:
                    user_path, _ = winreg.QueryValueEx(key, 'PATH')
                except FileNotFoundError:
                    user_path = ''

                if bin_dir_str not in user_path:
                    new_path = f"{user_path};{bin_dir_str}" if user_path else bin_dir_str
                    winreg.SetValueEx(key, 'PATH', 0, winreg.REG_EXPAND_SZ, new_path)
                    click.secho(f"Added {bin_dir} to user PATH", fg='green')
                    click.echo("Restart your terminal for the change to take effect")
                    winreg.CloseKey(key)
                    return True
            except Exception as e:
                click.secho(f"Warning: Could not update PATH automatically: {e}", fg='yellow')
                click.echo(f"Please manually add {bin_dir} to your PATH")
                return False

        click.secho(f"Global command 'includecpp' is ready at {script_path}", fg='green')
        return True

    elif system in ["Linux", "Darwin"]:
        bin_dir = Path.home() / '.local' / 'bin'
        bin_dir.mkdir(parents=True, exist_ok=True)

        script_path = bin_dir / 'includecpp'
        with open(script_path, 'w') as f:
            f.write('#!/usr/bin/env bash\n')
            f.write(f'exec "{sys.executable}" -m includecpp "$@"\n')

        script_path.chmod(0o755)

        current_path = os.environ.get('PATH', '')
        bin_dir_str = str(bin_dir)

        if bin_dir_str in current_path:
            click.secho(f"Global command 'includecpp' is ready at {script_path}", fg='green')
        else:
            click.secho(f"Created wrapper script at {script_path}", fg='green')
            click.echo(f"Add {bin_dir} to your PATH by adding this to ~/.bashrc or ~/.zshrc:")
            click.echo(f'  export PATH="$PATH:{bin_dir}"')

        return True

    return False

@cli.command()
def init():
    config_file = Path.cwd() / "cpp.proj"
    if config_file.exists():
        click.echo("cpp.proj already exists")
        return

    CppProjectConfig.create_default('cpp.proj')
    click.echo("Created cpp.proj configuration")
    click.echo("Created include/ directory")
    click.echo("Created plugins/ directory")

    marker_file = Path.home() / '.includecpp_global_setup'
    if not marker_file.exists():
        click.echo()
        if _setup_global_command():
            marker_file.touch()
            click.echo()
            click.echo("You can now use 'includecpp <command>' instead of 'python -m includecpp <command>'")

@cli.command()
@click.option('--clean', is_flag=True, help='Force clean rebuild (ignore incremental)')
@click.option('--full', is_flag=True, help='Complete rebuild including plugin_gen.exe and all caches')
@click.option('--verbose', is_flag=True, help='Verbose output')
@click.option('--no-incremental', is_flag=True, help='Disable incremental builds')
@click.option('--incremental', is_flag=True, help='Explicitly enable incremental builds (default: auto)')
@click.option('--parallel/--no-parallel', default=True, help='Enable/disable parallel compilation (default: enabled)')
@click.option('--jobs', '-j', type=int, default=4, help='Max parallel jobs (default: 4)')
@click.option('--modules', '-m', multiple=True, help='Specific modules to rebuild')
@click.option('--this', 'build_paths', multiple=True, type=click.Path(exists=True),
              help='Build only from specific paths (can specify multiple)')
@click.option('--fast', 'fast_plugin', type=str, default=None,
              help='Fast incremental rebuild of single plugin (e.g., algorithms.cp)')
@click.option('--all', 'fast_all', is_flag=True, help='With --fast: rebuild all plugins incrementally')
def rebuild(clean, full, verbose, no_incremental, incremental, parallel, jobs, modules,
            build_paths, fast_plugin, fast_all):
    """v2.0: Rebuild C++ modules with incremental and parallel support."""
    from ..core.build_manager import BuildManager
    from ..core.error_formatter import BuildErrorFormatter

    project_root = Path.cwd()
    config = CppProjectConfig()

    compiler = detect_compiler()
    build_dir = config.get_build_dir(compiler)

    # Full rebuild: delete everything including generator
    if full and build_dir.exists():
        click.echo("Full rebuild: Deleting entire build directory including plugin_gen.exe...")
        shutil.rmtree(build_dir)
        clean = True  # Force clean mode

    # Clean if requested
    elif clean and build_dir.exists():
        click.echo("Cleaning build directory...")
        shutil.rmtree(build_dir)

    build_dir.mkdir(parents=True, exist_ok=True)
    config.update_base_dir(build_dir)

    click.echo(f"Build directory: {build_dir}")

    if incremental and no_incremental:
        click.secho("Error: Cannot use both --incremental and --no-incremental", fg='red', err=True)
        raise click.Abort()

    if clean and incremental:
        click.secho("Warning: --clean overrides --incremental", fg='yellow')
        incremental = False

    if fast_plugin and build_paths:
        click.secho("Error: Cannot use both --fast and --this", fg='red', err=True)
        raise click.Abort()

    if fast_all and not fast_plugin:
        click.secho("Error: --all requires --fast <plugin>", fg='red', err=True)
        raise click.Abort()

    final_incremental = True
    if incremental:
        final_incremental = True
    elif no_incremental or clean:
        final_incremental = False

    discovered_modules = []
    if build_paths:
        if verbose:
            click.echo(f"Discovering modules in {len(build_paths)} path(s)...")

        from ..core.path_discovery import PathDiscovery
        discoverer = PathDiscovery(project_root, config)

        for path in build_paths:
            path_obj = Path(path)
            found = discoverer.discover_modules_in_path(path_obj)
            discovered_modules.extend(found)
            if verbose:
                click.echo(f"  {path}: found {len(found)} module(s)")

        if discovered_modules:
            modules = tuple(discovered_modules)
            if verbose:
                click.echo(f"Building {len(modules)} discovered module(s): {', '.join(modules)}")
        else:
            click.secho("No modules found in specified paths", fg='yellow')
            raise click.Abort()

    if fast_plugin and not fast_all:
        if verbose:
            click.echo(f"Fast rebuild mode: {fast_plugin}")

        if fast_plugin.endswith('.cp'):
            module_name = fast_plugin[:-3]
        else:
            module_name = fast_plugin

        from ..core.build_manager import BuildManager
        temp_builder = BuildManager(project_root, build_dir, config)
        registry = temp_builder._load_registry()
        available_modules = registry.get('modules', {})

        if module_name not in available_modules:
            click.secho(f"Module '{module_name}' not found", fg='red', err=True)
            click.echo(f"Available modules: {', '.join(available_modules.keys())}")
            raise click.Abort()

        dep_graph = temp_builder._build_dependency_graph(available_modules)
        affected_modules = temp_builder._get_affected_modules(module_name, dep_graph, available_modules)

        modules = tuple(affected_modules)
        final_incremental = True
        clean = False

        if verbose:
            click.echo(f"Affected modules ({len(modules)}): {', '.join(modules)}")

    if fast_all:
        if verbose:
            click.echo("Fast rebuild mode: ALL plugins")

        final_incremental = True
        clean = False
        modules = None

        if verbose:
            click.echo("Will rebuild all changed plugins incrementally")

    # v2.0: Show build configuration
    if verbose:
        click.echo(f"Incremental: {final_incremental}")
        click.echo(f"Parallel: {parallel}")
        if parallel:
            click.echo(f"Max jobs: {jobs}")
        if modules:
            click.echo(f"Target modules: {', '.join(modules)}")

    click.echo("Building C++ modules...")

    try:
        builder = BuildManager(project_root, build_dir, config)

        success = builder.rebuild(
            modules=list(modules) if modules else None,
            incremental=final_incremental,
            parallel=parallel,
            clean=clean,
            verbose=verbose
        )

        if success:
            click.echo("\n✓ Build completed successfully!")
        else:
            click.echo("\n✗ Build failed", err=True)
            raise click.Abort()

    except Exception as e:
        # v2.0: Enhanced error messages
        error_msg = str(e)

        # Check for specific error types
        if "circular dependency" in error_msg.lower():
            click.echo("\n" + error_msg, err=True)
        elif "depends on unknown module" in error_msg.lower():
            click.echo("\n" + error_msg, err=True)
        else:
            click.echo(f"\n✗ Build failed: {e}", err=True)

        if verbose:
            import traceback
            traceback.print_exc()

        raise click.Abort()

@cli.command()
@click.argument('module_name')
def add(module_name):
    """Create a new module template."""
    plugins_dir = Path("plugins")
    if not plugins_dir.exists():
        click.echo("Error: plugins/ directory not found")
        return

    cp_file = plugins_dir / f"{module_name}.cp"
    if cp_file.exists():
        click.echo(f"Module {module_name} already exists")
        return

    template = f"""SOURCE(include/{module_name}.cpp) {module_name}

PUBLIC(
    {module_name} FUNC(example_function)
)
"""

    with open(cp_file, 'w') as f:
        f.write(template)

    click.echo(f"Created {cp_file}")
    click.echo(f"Now create include/{module_name}.cpp with your C++ code")

@cli.command()
def list():
    """List all available C++ modules."""
    from ..core.build_manager import BuildManager

    project_root = Path.cwd()
    config = CppProjectConfig()
    compiler = detect_compiler()
    build_dir = config.get_build_dir(compiler)

    if not build_dir.exists():
        click.echo("No build directory found. Run 'python -m includecpp rebuild' first.")
        return

    try:
        builder = BuildManager(project_root, build_dir, config)
        registry = builder._load_registry()

        modules = registry.get('modules', {})
        if not modules:
            click.echo("No modules found. Run 'python -m includecpp rebuild' to build modules.")
            return

        click.echo(f"\nAvailable modules ({len(modules)}):")
        click.echo("=" * 60)

        for module_name, module_info in sorted(modules.items()):
            # Get source count
            sources = module_info.get('sources', [])
            source_count = len(sources)

            # Get dependency count
            deps = module_info.get('dependencies', [])
            dep_count = len(deps)

            # Get struct/class/function counts
            structs = module_info.get('structs', [])
            classes = module_info.get('classes', [])
            functions = module_info.get('functions', [])

            click.echo(f"\n  {module_name}")
            click.echo(f"    Sources: {source_count} file(s)")

            if dep_count > 0:
                dep_names = [d.get('target', '?') for d in deps]
                click.echo(f"    Dependencies: {', '.join(dep_names)}")

            if structs:
                click.echo(f"    Structs: {len(structs)}")
            if classes:
                click.echo(f"    Classes: {len(classes)}")
            if functions:
                click.echo(f"    Functions: {len(functions)}")

        click.echo("\n" + "=" * 60)
        click.echo(f"Total: {len(modules)} module(s)\n")

    except Exception as e:
        click.echo(f"Error: {e}", err=True)

@cli.command()
@click.argument('module_name')
def info(module_name):
    """Show detailed information about a module."""
    from ..core.build_manager import BuildManager

    project_root = Path.cwd()
    config = CppProjectConfig()
    compiler = detect_compiler()
    build_dir = config.get_build_dir(compiler)

    if not build_dir.exists():
        click.echo("No build directory found. Run 'python -m includecpp rebuild' first.")
        return

    try:
        builder = BuildManager(project_root, build_dir, config)
        registry = builder._load_registry()

        modules = registry.get('modules', {})
        if module_name not in modules:
            click.echo(f"Module '{module_name}' not found.")
            click.echo(f"Available modules: {', '.join(sorted(modules.keys()))}")
            return

        module_info = modules[module_name]

        click.echo(f"\nModule: {module_name}")
        click.echo("=" * 60)

        # Sources
        sources = module_info.get('sources', [])
        click.echo(f"\nSources ({len(sources)}):")
        for src in sources:
            click.echo(f"  • {src}")

        # Dependencies
        deps = module_info.get('dependencies', [])
        if deps:
            click.echo(f"\nDependencies ({len(deps)}):")
            for dep in deps:
                target = dep.get('target', '?')
                types = dep.get('types', [])
                if types:
                    click.echo(f"  • {target} (types: {', '.join(types)})")
                else:
                    click.echo(f"  • {target}")

        # Structs
        structs = module_info.get('structs', [])
        if structs:
            click.echo(f"\nStructs ({len(structs)}):")
            for struct in structs:
                name = struct.get('name', '?')
                is_template = struct.get('is_template', False)
                if is_template:
                    template_types = struct.get('template_types', [])
                    click.echo(f"  • {name}<{', '.join(template_types)}>")
                else:
                    click.echo(f"  • {name}")

                fields = struct.get('fields', [])
                if fields:
                    for field in fields:
                        field_type = field.get('type', '?')
                        field_name = field.get('name', '?')
                        click.echo(f"      - {field_type} {field_name}")

        # Classes
        classes = module_info.get('classes', [])
        if classes:
            click.echo(f"\nClasses ({len(classes)}):")
            for cls in classes:
                name = cls.get('name', '?')
                methods = cls.get('methods', [])
                click.echo(f"  • {name}")
                if methods:
                    click.echo(f"      Methods: {', '.join(methods)}")

        # Functions
        functions = module_info.get('functions', [])
        if functions:
            click.echo(f"\nFunctions ({len(functions)}):")
            for func in functions:
                name = func.get('name', '?')
                click.echo(f"  • {name}()")

        # Build info
        last_built = module_info.get('last_built', 'Never')
        build_time = module_info.get('build_time_ms', 0)
        click.echo(f"\nLast Built: {last_built}")
        if build_time > 0:
            click.echo(f"Build Time: {build_time}ms")

        click.echo("=" * 60 + "\n")

    except Exception as e:
        click.echo(f"Error: {e}", err=True)

@cli.command()
@click.argument('module_name', required=False)
@click.option('--list-all', is_flag=True, help='List all available modules')
def install(module_name, list_all):
    """Install a module from GitHub: https://github.com/liliassg/IncludeCPP/minstall/{module}"""
    import tempfile
    import urllib.request
    import urllib.error
    import json

    # Handle --list-all option
    if list_all:
        click.echo("=" * 60)
        click.secho("Available IncludeCPP Modules", fg='cyan', bold=True)
        click.echo("=" * 60)
        click.echo(f"Source: https://github.com/liliassg/IncludeCPP/tree/main/minstall")
        click.echo()

        try:
            # Fetch directory listing from GitHub API
            api_url = "https://api.github.com/repos/liliassg/IncludeCPP/contents/minstall"
            click.echo("  Fetching module list...", nl=False)

            with urllib.request.urlopen(api_url) as response:
                data = json.loads(response.read())
                click.secho(" OK", fg='green')
                click.echo()

            # Extract module names (directories)
            modules = [item['name'] for item in data if item['type'] == 'dir']

            if not modules:
                click.secho("  No modules found.", fg='yellow')
            else:
                click.secho(f"Found {len(modules)} module(s):", fg='green', bold=True)
                click.echo()
                for module in sorted(modules):
                    click.echo(f"  • {module}")

                click.echo()
                click.echo("Install a module with:")
                click.echo("  includecpp install <module_name>")

        except urllib.error.HTTPError as e:
            click.secho(f"  FAILED (HTTP {e.code})", fg='red', err=True)
            click.echo()
            click.echo("Could not fetch module list from GitHub.")
        except Exception as e:
            click.secho(f"  FAILED ({e})", fg='red', err=True)

        click.echo("=" * 60)
        return

    # Require module_name if not using --list-all
    if not module_name:
        click.secho("Error: Missing argument 'MODULE_NAME'.", fg='red', err=True)
        click.echo("Use 'includecpp install --list-all' to see available modules.")
        return

    # Check if include and plugins directories exist
    include_dir = Path.cwd() / "include"
    plugins_dir = Path.cwd() / "plugins"

    if not include_dir.exists() or not plugins_dir.exists():
        click.secho("Error: Not in a valid IncludeCPP project directory.", fg='red', err=True)
        click.echo("Run 'python -m includecpp init' first.")
        return

    click.echo("=" * 60)
    click.secho(f"Collecting {module_name}", fg='cyan', bold=True)
    click.echo("=" * 60)
    click.echo(f"Source: https://github.com/liliassg/IncludeCPP/tree/main/minstall/{module_name}")
    click.echo()

    # GitHub raw content base URL
    base_url = f"https://raw.githubusercontent.com/liliassg/IncludeCPP/main/minstall/{module_name}/"

    # Try to download .cp, .cpp, and .h files
    files_to_download = [
        (f"{module_name}.cp", plugins_dir, "Plugin definition"),
        (f"{module_name}.cpp", include_dir, "C++ implementation"),
        (f"{module_name}.h", include_dir, "C++ header")
    ]

    downloaded = []

    for filename, target_dir, description in files_to_download:
        url = base_url + filename
        target_path = target_dir / filename

        try:
            click.echo(f"  Collecting {filename:20} ({description})...", nl=False)
            with urllib.request.urlopen(url) as response:
                content = response.read()

                # Write to target directory
                with open(target_path, 'wb') as f:
                    f.write(content)

                downloaded.append(filename)
                file_size_kb = len(content) / 1024
                click.secho(f" OK ({file_size_kb:.1f} KB)", fg='green')

        except urllib.error.HTTPError as e:
            if e.code == 404:
                # File doesn't exist, skip (optional file like .h)
                click.secho(" SKIP (optional)", fg='yellow')
            else:
                click.secho(f" FAILED ({e})", fg='red', err=True)
        except Exception as e:
            click.secho(f" FAILED ({e})", fg='red', err=True)

    click.echo()

    if not downloaded:
        click.secho(f"Error: Module '{module_name}' not found or no files available.", fg='red', err=True)
        click.echo(f"Check https://github.com/liliassg/IncludeCPP/tree/main/minstall for available modules.")
        return

    click.secho(f"Successfully installed {len(downloaded)} file(s):", fg='green', bold=True)
    for f in downloaded:
        click.echo(f"  - {f}")

    click.echo()
    click.secho(f"Module '{module_name}' installed successfully!", fg='green', bold=True)
    click.echo("Run 'python -m includecpp rebuild' to build the module.")
    click.echo("=" * 60)

@cli.command()
@click.argument('module_name', required=False)
@click.option('--list-all', is_flag=True, help='List all available modules')
def minstall(module_name, list_all):
    """Alias for 'install' - Install modules from GitHub minstall repository."""
    # Call the install command with the same arguments
    ctx = click.get_current_context()
    ctx.invoke(install, module_name=module_name, list_all=list_all)

@cli.command()
def update():
    """Update IncludeCPP package to latest version from PyPI."""
    import subprocess
    import urllib.request
    import json

    click.echo("=" * 60)
    click.secho("Checking for IncludeCPP updates", fg='cyan', bold=True)
    click.echo("=" * 60)
    click.echo()

    try:
        click.echo("  Fetching latest version from PyPI...", nl=False)
        with urllib.request.urlopen("https://pypi.org/pypi/IncludeCPP/json") as response:
            data = json.loads(response.read())
            latest_version = data['info']['version']
            click.secho(f" OK", fg='green')

        from .. import __version__ as current_version
        click.echo()
        click.echo(f"  Current version: {current_version}")
        click.echo(f"  Latest version:  {latest_version}")
        click.echo()

        if current_version == latest_version:
            click.secho("IncludeCPP is already up to date!", fg='green', bold=True)
            click.echo("=" * 60)
            return

        click.secho(f"Upgrading to version {latest_version}...", fg='cyan', bold=True)
        click.echo()

        result = subprocess.run(
            [sys.executable, "-m", "pip", "install", "--upgrade", "IncludeCPP"],
            capture_output=True,
            text=True
        )

        if result.returncode == 0:
            click.echo()
            click.secho(f"Successfully upgraded to IncludeCPP {latest_version}!", fg='green', bold=True)
            click.echo("Restart your terminal to use the new version.")
        else:
            click.secho("Upgrade failed!", fg='red', err=True, bold=True)
            click.echo(result.stderr)

    except Exception as e:
        click.secho(f"Failed to check for updates: {e}", fg='red', err=True)

    click.echo("=" * 60)

@cli.command()
@click.argument('plugin_name')
@click.argument('files', nargs=-1, required=True)
@click.option('--private', '-p', multiple=True, help='Private functions to exclude from public API')
def plugin(plugin_name, files, private):
    import re
    from pathlib import Path

    project_root = Path.cwd()
    plugins_dir = project_root / "plugins"

    if not plugins_dir.exists():
        click.secho("Error: plugins/ directory not found", fg='red', err=True)
        click.echo("Run 'python -m includecpp init' first")
        return

    cpp_files = []
    h_files = []

    for file_path in files:
        p = Path(file_path)
        if not p.is_absolute():
            p = project_root / p

        if not p.exists():
            click.secho(f"Error: File not found: {file_path}", fg='red', err=True)
            return

        if p.suffix == '.cpp':
            cpp_files.append(p)
        elif p.suffix == '.h':
            h_files.append(p)

    if not cpp_files:
        click.secho("Error: No .cpp files provided", fg='red', err=True)
        return

    classes = {}
    functions = set()
    namespaces = set()

    all_files = cpp_files + h_files

    for file in all_files:
        with open(file, 'r', encoding='utf-8') as f:
            content = f.read()

        namespace_matches = re.findall(r'namespace\s+(\w+)', content)
        namespaces.update(namespace_matches)

        class_pattern = r'(?:class|struct)\s+(\w+)\s*(?:{|:)[^}]*?public:\s*([^}]*?)(?:private:|protected:|};)'
        class_matches = re.finditer(class_pattern, content, re.DOTALL)

        for match in class_matches:
            class_name = match.group(1)
            public_section = match.group(2)

            if class_name not in classes:
                classes[class_name] = {'methods': set(), 'constructors': 0}

            method_pattern = r'(?:virtual|static|inline|explicit)?\s*[\w:]+\s+(\w+)\s*\([^)]*\)'
            constructor_pattern = rf'{class_name}\s*\([^)]*\)'

            methods = re.findall(method_pattern, public_section)
            classes[class_name]['methods'].update(m for m in methods if m != class_name)

            constructors = re.findall(constructor_pattern, public_section)
            if constructors:
                classes[class_name]['constructors'] = len(constructors)

        func_matches = re.findall(r'^(?:(?:inline|static|virtual|explicit|constexpr)\s+)*(?:[\w:]+(?:<[^>]+>)?)\s+(\w+)\s*\([^)]*\)(?:\s*(?:const|override|final|noexcept))*\s*(?:{|;)', content, re.MULTILINE)
        functions.update(func_matches)

    private_set = set(private) if private else set()
    public_functions = functions - private_set - set(classes.keys())

    cp_file = plugins_dir / f"{plugin_name}.cp"

    cpp_sources = ' '.join(str(f.relative_to(project_root) if f.is_relative_to(project_root) else f).replace('\\', '/') for f in cpp_files)
    h_headers = ' '.join(str(f.relative_to(project_root) if f.is_relative_to(project_root) else f).replace('\\', '/') for f in h_files) if h_files else None

    with open(cp_file, 'w') as f:
        if h_headers:
            f.write(f'SOURCE({cpp_sources}) && HEADER({h_headers}) {plugin_name}\n\n')
        else:
            f.write(f'SOURCE({cpp_sources}) {plugin_name}\n\n')

        if classes or public_functions:
            f.write('PUBLIC(\n')

            for cls_name in sorted(classes.keys()):
                cls_info = classes[cls_name]
                f.write(f'    {plugin_name} CLASS({cls_name}) {{\n')

                if cls_info['constructors'] > 0:
                    f.write(f'        CONSTRUCTOR()\n')

                for method in sorted(cls_info['methods']):
                    f.write(f'        METHOD({method})\n')

                f.write(f'    }}\n')

            if classes and public_functions:
                f.write('\n')

            for func in sorted(public_functions):
                if not any(c.lower() in func.lower() or func.lower() in c.lower() for c in classes.keys()):
                    f.write(f'    {plugin_name} FUNCTION({func})\n')

            f.write(')\n')

    click.secho(f"Generated plugin: {cp_file}", fg='green', bold=True)
    click.echo(f"Classes found: {len(classes)}")
    click.echo(f"Public functions: {len(public_functions)}")
    if private_set:
        click.echo(f"Private functions excluded: {len(private_set)}")
    click.echo()
    click.echo("Run 'python -m includecpp rebuild' to build the plugin")

def detect_compiler():
    for compiler in ['g++', 'clang++', 'cl']:
        if shutil.which(compiler):
            return compiler.replace('++', '').replace('cl', 'msvc')
    return 'gcc'

if __name__ == '__main__':
    cli()
