import configparser
import os
from pathlib import Path
from typing import Any

import boto3

from minimls.config import get_env_config


def _ensure_credentials(env: str) -> None:
    cfg = get_env_config(env)
    profile_name = f"mls-{env}"

    credential_process = (
        f"{cfg['signing_helper']} credential-process"
        f" --certificate {cfg['certificate']}"
        f" --private-key {cfg['private_key']}"
        f" --trust-anchor-arn {cfg['trust_anchor_arn']}"
        f" --profile-arn {cfg['profile_arn']}"
        f" --role-arn {cfg['role_arn']}"
    )

    credentials_path = Path(os.path.expanduser("~/.aws/credentials"))
    credentials_path.parent.mkdir(parents=True, exist_ok=True)

    config = configparser.ConfigParser()
    if credentials_path.exists():
        config.read(credentials_path)

    config[profile_name] = {"credential_process": credential_process}

    with credentials_path.open("w") as f:
        config.write(f)


class MLSClient:
    def __init__(self, env: str, bucket_name: str):
        if env not in ("prd", "stg"):
            raise ValueError(f"env must be 'prd' or 'stg', got {env!r}")

        self.env = env
        self.bucket_name = bucket_name
        self._profile_name = f"mls-{env}"

        _ensure_credentials(self.env)

        session = boto3.Session(profile_name=self._profile_name)
        self._client = session.client("s3")

    def upload_object(self, file_path: str, key: str) -> None:
        self._client.upload_file(Filename=file_path, Bucket=self.bucket_name, Key=key)

    def download_object(self, key: str, file_path: str) -> None:
        self._client.download_file(Bucket=self.bucket_name, Key=key, Filename=file_path)

    def list_objects(self, prefix: str = "") -> list[dict[str, Any]]:
        results = []
        paginator = self._client.get_paginator("list_objects_v2")
        for page in paginator.paginate(Bucket=self.bucket_name, Prefix=prefix):
            results.extend(page.get("Contents", []))
        return results
