#!/usr/bin/env python3
"""
Setup script to configure llama3.2 with AirLLM using local model path (no tokens after initial download).

This script will:
1. Download llama3.2 to a local directory (one-time token needed)
2. Configure nanobot to use the local path (no tokens needed after)
"""

import json
import os
import sys
from pathlib import Path

CONFIG_PATH = Path.home() / ".nanobot" / "config.json"
MODEL_DIR = Path.home() / ".local" / "models" / "llama3.2-3b-instruct"
MODEL_NAME = "meta-llama/Llama-3.2-3B-Instruct"

def load_existing_config():
    """Load existing config or return default."""
    if CONFIG_PATH.exists():
        try:
            with open(CONFIG_PATH) as f:
                return json.load(f)
        except Exception as e:
            print(f"Warning: Could not read existing config: {e}")
            return {}
    return {}

def download_model_with_token():
    """Download model using Hugging Face token."""
    print("\n" + "="*70)
    print("DOWNLOADING LLAMA3.2 MODEL")
    print("="*70)
    print(f"\nThis will download {MODEL_NAME} to:")
    print(f"  {MODEL_DIR}")
    print("\nYou'll need a Hugging Face token (one-time only).")
    print("After download, no tokens will be needed!\n")
    
    has_token = input("Do you have a Hugging Face token? (y/n): ").strip().lower()
    
    if has_token != 'y':
        print("\n" + "="*70)
        print("GETTING A HUGGING FACE TOKEN")
        print("="*70)
        print("\n1. Go to: https://huggingface.co/settings/tokens")
        print("2. Click 'New token'")
        print("3. Give it a name (e.g., 'nanobot')")
        print("4. Select 'Read' permission")
        print("5. Click 'Generate token'")
        print("6. Copy the token (starts with 'hf_...')")
        print("\nThen accept the Llama license:")
        print(f"1. Go to: https://huggingface.co/{MODEL_NAME}")
        print("2. Click 'Agree and access repository'")
        print("3. Accept the license terms")
        print("\nRun this script again after getting your token.")
        return False
    
    hf_token = input("\nEnter your Hugging Face token (starts with 'hf_'): ").strip()
    if not hf_token or not hf_token.startswith('hf_'):
        print("⚠ Error: Token must start with 'hf_'")
        return False
    
    print(f"\nDownloading {MODEL_NAME}...")
    print("This may take a while depending on your internet connection...")
    
    try:
        from huggingface_hub import snapshot_download
        import os
        
        # Set token as environment variable
        os.environ['HF_TOKEN'] = hf_token
        
        # Download to local directory
        MODEL_DIR.parent.mkdir(parents=True, exist_ok=True)
        
        snapshot_download(
            repo_id=MODEL_NAME,
            local_dir=str(MODEL_DIR),
            token=hf_token,
            local_dir_use_symlinks=False
        )
        
        print(f"\n✓ Model downloaded successfully to: {MODEL_DIR}")
        return True
        
    except ImportError:
        print("\n⚠ Error: huggingface_hub not installed.")
        print("Install it with: pip install huggingface_hub")
        return False
    except Exception as e:
        print(f"\n⚠ Error downloading model: {e}")
        print("\nYou can try downloading manually:")
        print(f"  huggingface-cli download {MODEL_NAME} --local-dir {MODEL_DIR} --token {hf_token[:10]}...")
        return False

def check_model_exists():
    """Check if model is already downloaded locally."""
    # Check for common model files
    required_files = ['config.json', 'tokenizer.json']
    if MODEL_DIR.exists():
        has_files = all((MODEL_DIR / f).exists() for f in required_files)
        if has_files:
            print(f"✓ Found existing model at: {MODEL_DIR}")
            return True
    return False

def configure_for_local_path(config):
    """Configure nanobot to use local model path."""
    # Ensure providers section exists
    if "providers" not in config:
        config["providers"] = {}
    
    # Ensure agents section exists
    if "agents" not in config:
        config["agents"] = {}
    if "defaults" not in config["agents"]:
        config["agents"]["defaults"] = {}
    
    # Set up AirLLM provider with local path
    config["providers"]["airllm"] = {
        "apiKey": str(MODEL_DIR),  # Local path - no tokens needed!
        "apiBase": None,
        "extraHeaders": {}  # No hf_token needed for local paths
    }
    
    # Set default model to local path
    config["agents"]["defaults"]["model"] = str(MODEL_DIR)
    
    return config

def save_config(config):
    """Save config to file."""
    CONFIG_PATH.parent.mkdir(parents=True, exist_ok=True)
    with open(CONFIG_PATH, 'w') as f:
        json.dump(config, f, indent=2)
    
    # Set secure permissions
    os.chmod(CONFIG_PATH, 0o600)
    print(f"\n✓ Configuration saved to: {CONFIG_PATH}")

def main():
    """Main setup function."""
    print("\n" + "="*70)
    print("LLAMA3.2 + AIRLLM LOCAL SETUP (NO TOKENS AFTER DOWNLOAD)")
    print("="*70)
    
    # Check if model already exists
    if check_model_exists():
        print("\nModel already downloaded! Configuring...")
        config = load_existing_config()
        config = configure_for_local_path(config)
        save_config(config)
        print("\n✓ Configuration complete!")
        print(f"  Model path: {MODEL_DIR}")
        print("  No tokens needed - using local model!")
        return
    
    # Check if user wants to download
    print(f"\nModel not found at: {MODEL_DIR}")
    download = input("\nDownload model now? (y/n): ").strip().lower()
    
    if download == 'y':
        if download_model_with_token():
            # Configure after successful download
            config = load_existing_config()
            config = configure_for_local_path(config)
            save_config(config)
            print("\n" + "="*70)
            print("SETUP COMPLETE!")
            print("="*70)
            print(f"\n✓ Model downloaded to: {MODEL_DIR}")
            print(f"✓ Configuration updated to use local path")
            print("\n🎉 No tokens needed anymore - using local model!")
            print("\nTest it with:")
            print("  nanobot agent -m 'Hello, what is 2+5?'")
        else:
            print("\n⚠ Download failed. You can:")
            print("  1. Run this script again")
            print("  2. Download manually and point config to the path")
    else:
        # Just configure for local path (user will provide model)
        print(f"\nConfiguring for local path: {MODEL_DIR}")
        print("Make sure the model is downloaded to this location.")
        config = load_existing_config()
        config = configure_for_local_path(config)
        save_config(config)
        print("\n✓ Configuration saved!")
        print(f"\nTo download the model manually:")
        print(f"  huggingface-cli download {MODEL_NAME} --local-dir {MODEL_DIR}")
        print("\nOr place your model files in:")
        print(f"  {MODEL_DIR}")

if __name__ == "__main__":
    main()

