#!/usr/bin/env python3
"""
Script to register Odoo module repos on apps.odoo.com

This script discovers git repositories in a given folder, registers them
on apps.odoo.com, and enables auto-scan for each repository.
"""

import json
import os
import re
import subprocess
import sys
import webbrowser
from pathlib import Path

try:
    import requests
except ImportError:
    print("Error: requests library is required. Install it with: pip install requests")
    sys.exit(1)


COOKIE_INSTRUCTIONS = """
To get your apps.odoo.com session_id:

1. Open your browser and go to: https://apps.odoo.com/apps/login
2. Log in to your account
3. Open Developer Tools (F12 or right-click -> Inspect)
4. Go to the "Application" tab (Chrome) or "Storage" tab (Firefox)
5. Expand "Cookies" and select https://apps.odoo.com
6. Find the "session_id" cookie value
7. Copy only the session_id value (not the "session_id=" part)

Example session_id:
uClcf_a6u8TFfkrmJ3BrP4yY3EK-zqDw8C8lhRjBRP_WReMx0ORtGLinkNnhn0DX251njzQy_5ym19A6Q2MS

Or you can enter the full cookie string:
frontend_lang=en_US; session_id=abc123...; tz=Europe/Paris
"""


def prompt_for_cookie():
    """Prompt user for apps.odoo.com cookie or session_id."""
    print("\n" + "=" * 70)
    print("COOKIE REQUIRED")
    print("=" * 70)
    print(COOKIE_INSTRUCTIONS)
    print("=" * 70)
    
    while True:
        value = input("\nEnter your session_id or full cookie: ").strip()
        
        if not value:
            print("Error: Value cannot be empty. Please try again.")
            continue
        
        if "session_id=" in value:
            cookie = value
        else:
            cookie = f"frontend_lang=en_US; session_id={value}; tz=Europe/Paris"
        
        if "session_id" not in cookie:
            print("\nWarning: Value does not appear to contain a session_id.")
            response = input("Do you want to continue anyway? (y/N): ").strip().lower()
            if response != 'y':
                continue
        
        return cookie


def get_git_remote_url(git_folder):
    """Get the SSH remote URL from a git repository."""
    try:
        result = subprocess.run(
            ["git", "remote", "get-url", "origin"],
            cwd=git_folder,
            capture_output=True,
            text=True,
            check=True
        )
        return result.stdout.strip()
    except subprocess.CalledProcessError:
        try:
            result = subprocess.run(
                ["git", "config", "remote.origin.url"],
                cwd=git_folder,
                capture_output=True,
                text=True,
                check=True
            )
            return result.stdout.strip()
        except subprocess.CalledProcessError:
            return None


def get_git_branch(git_folder):
    """Get the current branch name from a git repository."""
    try:
        result = subprocess.run(
            ["git", "rev-parse", "--abbrev-ref", "HEAD"],
            cwd=git_folder,
            capture_output=True,
            text=True,
            check=True
        )
        return result.stdout.strip()
    except subprocess.CalledProcessError:
        return None


def discover_git_repos(folder_path):
    """Discover all git repositories in the given folder."""
    repos = []
    folder_path = Path(folder_path)
    
    if not folder_path.exists():
        print(f"Error: Folder '{folder_path}' does not exist.")
        sys.exit(1)
    
    if not folder_path.is_dir():
        print(f"Error: '{folder_path}' is not a directory.")
        sys.exit(1)
    
    for item in folder_path.iterdir():
        if item.is_dir():
            git_dir = item / ".git"
            if git_dir.exists():
                remote_url = get_git_remote_url(str(item))
                branch = get_git_branch(str(item))
                
                if remote_url:
                    repos.append({
                        'path': str(item),
                        'remote_url': remote_url,
                        'branch': branch
                    })
                else:
                    print(f"Warning: Could not get remote URL for {item}")
    
    return repos


def register_repo(cookie, remote_url_with_branch):
    """Register a repository on apps.odoo.com."""
    url = "https://apps.odoo.com/apps/upload_repo"
    
    headers = {
        'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0',
        'Accept': '*/*',
        'Accept-Language': 'en-US,en;q=0.5',
        'Content-Type': 'application/json',
        'Origin': 'https://apps.odoo.com',
        'Referer': 'https://apps.odoo.com/apps/upload',
        'Cookie': cookie,
    }
    
    payload = {
        'id': 0,
        'jsonrpc': '2.0',
        'method': 'call',
        'params': {
            'url': remote_url_with_branch
        }
    }
    
    try:
        response = requests.post(url, headers=headers, json=payload, timeout=30)
        return response.json()
    except requests.RequestException as e:
        return {'error': f'Request failed: {str(e)}'}


def enable_auto_scan(cookie, repo_id):
    """Enable auto-scan for a repository on apps.odoo.com."""
    url = "https://apps.odoo.com/apps/repo_auto_scan"
    
    headers = {
        'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0',
        'Accept': '*/*',
        'Accept-Language': 'en-US,en;q=0.5',
        'Content-Type': 'application/json',
        'Origin': 'https://apps.odoo.com',
        'Referer': 'https://apps.odoo.com/apps/dashboard/repos',
        'Cookie': cookie,
    }
    
    payload = {
        'id': 0,
        'jsonrpc': '2.0',
        'method': 'call',
        'params': {
            'repo_id': str(repo_id),
            'auto_scan': True
        }
    }
    
    try:
        response = requests.post(url, headers=headers, json=payload, timeout=30)
        return response.json()
    except requests.RequestException as e:
        return {'error': f'Request failed: {str(e)}'}


def trigger_scan(cookie, repo_id):
    """Trigger a manual scan for a repository on apps.odoo.com."""
    url = "https://apps.odoo.com/apps/scan_repo"
    
    headers = {
        'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0',
        'Accept': '*/*',
        'Accept-Language': 'en-US,en;q=0.5',
        'Content-Type': 'application/json',
        'Origin': 'https://apps.odoo.com',
        'Referer': 'https://apps.odoo.com/apps/dashboard/repos',
        'Cookie': cookie,
    }
    
    payload = {
        'id': 1,
        'jsonrpc': '2.0',
        'method': 'call',
        'params': {
            'repo_id': str(repo_id)
        }
    }
    
    try:
        response = requests.post(url, headers=headers, json=payload, timeout=30)
        return response.json()
    except requests.RequestException as e:
        return {'error': f'Request failed: {str(e)}'}


def extract_repo_info(remote_url, branch):
    """Extract repository information from remote URL and branch."""
    if branch:
        return f"{remote_url}#{branch}"
    return remote_url


def main():
    if len(sys.argv) < 2:
        print("Usage: ./register-module-repos <folder_path> [odoo_version]")
        print("\nExamples:")
        print("  ./register-module-repos addons")
        print("  ./register-module-repos addons 19.0")
        sys.exit(1)
    
    folder_path = sys.argv[1]
    odoo_version = sys.argv[2] if len(sys.argv) > 2 else None
    
    print(f"\nDiscovering git repositories in: {folder_path}")
    repos = discover_git_repos(folder_path)
    
    if odoo_version:
        print(f"Filtering for Odoo version: {odoo_version}")
        repos = [r for r in repos if r['branch'] == odoo_version]
    
    if not repos:
        if odoo_version:
            print(f"No git repositories found with branch '{odoo_version}'.")
        else:
            print("No git repositories found in the specified folder.")
        sys.exit(0)
    
    print(f"Found {len(repos)} git repository(s):\n")
    for i, repo in enumerate(repos, 1):
        branch_info = f" (branch: {repo['branch']})" if repo['branch'] else ""
        print(f"  {i}. {repo['path']}{branch_info}")
        print(f"     Remote: {repo['remote_url']}")
    
    cookie = prompt_for_cookie()
    
    print("\n" + "=" * 70)
    print("Registering repositories on apps.odoo.com")
    print("=" * 70 + "\n")
    
    success_count = 0
    error_count = 0
    skipped_count = 0
    
    for repo in repos:
        remote_with_branch = extract_repo_info(repo['remote_url'], repo['branch'])
        repo_path = Path(repo['path']).name
        
        print(f"\n[{repo_path}]")
        print(f"  URL: {remote_with_branch}")
        
        result = register_repo(cookie, remote_with_branch)
        
        if 'error' in result:
            if "already registered" in result.get('error', '').lower():
                print(f"  Status: Already registered (skipped)")
                skipped_count += 1
            else:
                print(f"  Status: Error - {result['error']}")
                error_count += 1
        elif 'result' in result:
            repo_result = result['result']
            if 'repo_id' in repo_result:
                repo_id = repo_result['repo_id']
                print(f"  Status: Registered (repo_id: {repo_id})")
                
                print(f"  Enabling auto-scan...")
                scan_result = enable_auto_scan(cookie, repo_id)
                
                if 'error' in scan_result:
                    print(f"  Auto-scan: Error - {scan_result['error']}")
                else:
                    print(f"  Auto-scan: Enabled successfully")
                
                success_count += 1
            elif 'error' in repo_result:
                if "already registered" in repo_result['error'].lower():
                    print(f"  Status: Already registered (skipped)")
                    skipped_count += 1
                else:
                    print(f"  Status: Error - {repo_result['error']}")
                    error_count += 1
            else:
                print(f"  Status: Unknown response - {repo_result}")
                error_count += 1
        else:
            print(f"  Status: Unexpected response - {result}")
            error_count += 1
    
    print("\n" + "=" * 70)
    print("Summary")
    print("=" * 70)
    print(f"  Total repositories: {len(repos)}")
    print(f"  Successfully registered: {success_count}")
    print(f"  Already registered (skipped): {skipped_count}")
    print(f"  Errors: {error_count}")
    print("=" * 70)


if __name__ == "__main__":
    main()
