#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os
import sys
from pathlib import Path

import boto3
from botocore.config import Config

S3_PREFIX = "World of Warcraft"
MANIFEST_S3_KEY = "manifest.json"


def load_dotenv(env_path: Path) -> dict[str, str]:
    values: dict[str, str] = {}
    if not env_path.exists():
        return values
    for raw_line in env_path.read_text(encoding="utf-8").splitlines():
        line = raw_line.strip()
        if not line or line.startswith("#") or "=" not in line:
            continue
        key, value = line.split("=", 1)
        key = key.strip()
        value = value.strip()
        if key.startswith("export "):
            key = key.removeprefix("export ").strip()
        if not key:
            continue
        if len(value) >= 2 and value[0] == value[-1] and value[0] in {"'", '"'}:
            value = value[1:-1]
        values[key] = value
    return values


def get_env(dotenv: dict[str, str], key: str) -> str:
    value = os.environ.get(key) or dotenv.get(key)
    if not value:
        print(f"ERROR: {key} is not set (env or .env)", file=sys.stderr)
        sys.exit(1)
    return value


def main() -> int:
    project_root = Path(__file__).resolve().parent
    dotenv = load_dotenv(project_root / ".env")

    bucket = get_env(dotenv, "AWS_BUCKET")
    endpoint = get_env(dotenv, "AWS_ENDPOINT")
    region = get_env(dotenv, "AWS_DEFAULT_REGION")
    access_key = get_env(dotenv, "AWS_ACCESS_KEY_ID")
    secret_key = get_env(dotenv, "AWS_SECRET_ACCESS_KEY")
    use_path_style = get_env(dotenv, "AWS_USE_PATH_STYLE_ENDPOINT").lower() == "true"

    s3 = boto3.client(
        "s3",
        endpoint_url=endpoint,
        region_name=region,
        aws_access_key_id=access_key,
        aws_secret_access_key=secret_key,
        config=Config(s3={"addressing_style": "path"}) if use_path_style else None,
    )

    dist_dir = project_root / "dist"
    if not dist_dir.exists():
        print(f"ERROR: dist/ directory not found. Run build first.", file=sys.stderr)
        return 1

    errors = False

    # Загрузка всех файлов из dist/ с сохранением относительных путей
    files = sorted(f for f in dist_dir.rglob("*") if f.is_file())
    if not files:
        print("ERROR: dist/ is empty, nothing to upload.", file=sys.stderr)
        return 1

    for local_path in files:
        rel_path = local_path.relative_to(dist_dir).as_posix()
        s3_key = f"{S3_PREFIX}/{rel_path}"
        size_mb = local_path.stat().st_size / (1024 * 1024)
        print(f"Uploading {rel_path} ({size_mb:.1f} MB) -> s3://{bucket}/{s3_key}")
        try:
            s3.upload_file(str(local_path), bucket, s3_key)
            print(f"  OK")
        except Exception as e:
            print(f"  ERROR: {e}", file=sys.stderr)
            errors = True

    # Загрузка манифеста
    manifest_path = project_root / "manifest.json"
    if not manifest_path.exists():
        print(f"ERROR: manifest.json not found", file=sys.stderr)
        return 1

    print(f"Uploading manifest.json -> s3://{bucket}/{MANIFEST_S3_KEY}")
    try:
        s3.upload_file(
            str(manifest_path),
            bucket,
            MANIFEST_S3_KEY,
            ExtraArgs={"ContentType": "application/json"},
        )
        print(f"  OK")
    except Exception as e:
        print(f"  ERROR: {e}", file=sys.stderr)
        errors = True

    if errors:
        print("\nFinished with errors.")
        return 1

    print("\nAll uploads completed successfully.")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
