# Copyright (c) 2023 CloudZero - ALL RIGHTS RESERVED - PROPRIETARY AND CONFIDENTIAL
# Unauthorized copying of this file and/or project, via any medium is strictly prohibited.
# Direct all questions to legal@cloudzero.com
from enum import Enum
from typing import NamedTuple

import boto3

DEV_CORE_ACCOUNT_ID = '618300337335'
DEV_REACTOR_ACCOUNT_ID = '998146006915'
PROD_CORE_ACCOUNT_ID = '931830253929'
PROD_REACTOR_ACCOUNT_ID = '061190967865'

DEFAULT_NAMESPACE_DEV = 'alfa'
DEFAULT_NAMESPACE_PROD = 'live'


class Environment(str, Enum):
    dev = 'dev'
    prod = 'prod'


class Account(str, Enum):
    core = 'core'
    reactor = 'reactor'


def default_namespace(environment: Environment) -> str:
    return {Environment.dev: DEFAULT_NAMESPACE_DEV, Environment.prod: DEFAULT_NAMESPACE_PROD}[environment]


def account_id(environment: Environment, account: Account) -> str:
    return {
        (Environment.dev, Account.core): DEV_CORE_ACCOUNT_ID,
        (Environment.dev, Account.reactor): DEV_REACTOR_ACCOUNT_ID,
        (Environment.prod, Account.core): PROD_CORE_ACCOUNT_ID,
        (Environment.prod, Account.reactor): PROD_REACTOR_ACCOUNT_ID,
    }[(environment, account)]


def reactor_account_id(environment: Environment) -> str:
    return account_id(environment, Account.reactor)


def core_account_id(environment: Environment) -> str:
    return account_id(environment, Account.core)


def environment(namespace: str) -> Environment:
    return Environment.prod if namespace == DEFAULT_NAMESPACE_PROD else Environment.dev


class AccountInfo(NamedTuple):
    environment: Environment
    account: Account

    @property
    def account_id(self) -> str:
        return account_id(self.environment, self.account)

    @property
    def default_namespace(self) -> str:
        return default_namespace(self.environment)

    @property
    def reactor_account_id(self) -> str:
        return reactor_account_id(self.environment)

    @property
    def core_account_id(self) -> str:
        return core_account_id(self.environment)

    @classmethod
    def from_namespace(cls, namespace: str, account: Account) -> 'AccountInfo':
        return cls(environment(namespace), account)


def resolve_account_info() -> AccountInfo:
    sts_client = boto3.client('sts')
    account_id = sts_client.get_caller_identity()['Account']
    return {
        DEV_CORE_ACCOUNT_ID: AccountInfo(Environment.dev, Account.core),
        DEV_REACTOR_ACCOUNT_ID: AccountInfo(Environment.dev, Account.reactor),
        PROD_CORE_ACCOUNT_ID: AccountInfo(Environment.prod, Account.core),
        PROD_REACTOR_ACCOUNT_ID: AccountInfo(Environment.prod, Account.reactor),
    }[account_id]
