import datetime
from typing import Any

from app import app
from app.extensions import db
from app.models.base import Group
from app.models.onions import Eotk
from app.terraform.terraform import TerraformAutomation


def update_eotk_instance(group_id: int,
                         region: str,
                         instance_id: str) -> None:
    instance = Eotk.query.filter(
        Eotk.group_id == group_id,
        Eotk.region == region,
        Eotk.provider == "aws",
        Eotk.destroyed.is_(None)
    ).first()
    if instance is None:
        instance = Eotk()
        instance.added = datetime.datetime.utcnow()
        instance.group_id = group_id
        instance.provider = "aws"
        instance.region = region
        db.session.add(instance)
    instance.updated = datetime.datetime.utcnow()
    instance.instance_id = instance_id


class EotkAWSAutomation(TerraformAutomation):
    short_name = "eotk_aws"
    description = "Deploy EOTK instances to AWS"

    template_parameters = [
        "aws_access_key",
        "aws_secret_key"
    ]

    template = """
    terraform {
      required_providers {
        aws = {
          version = "~> 4.4.0"
        }
      }
    }

    provider "aws" {
      access_key = "{{ aws_access_key }}"
      secret_key = "{{ aws_secret_key }}"
      region = "us-east-2"
    }

    provider "aws" {
      access_key = "{{ aws_access_key }}"
      secret_key = "{{ aws_secret_key }}"
      region = "eu-central-1"
      alias = "second_region"
    }

    {% for group in groups %}
    module "eotk_{{ group.id }}" {
      providers = {
        aws = aws,
        aws.second_region = aws.second_region
      }
      source = "sr2c/aws/eotk"
      version = "0.0.6"
      namespace = "{{ global_namespace }}"
      tenant = "{{ group.group_name }}"
      name = "eotk"
      label_order = ["namespace", "tenant", "name", "attributes"]
      disable_api_termination = true
    }
    {% endfor %}
    """

    def tf_generate(self) -> None:
        self.tf_write(
            self.template,
            groups=Group.query.filter(
                Group.eotk.is_(True),
                Group.destroyed.is_(None)
            ).all(),
            global_namespace=app.config['GLOBAL_NAMESPACE'],
            **{
                k: app.config[k.upper()]
                for k in self.template_parameters
            }
        )

    def tf_posthook(self, *, prehook_result: Any = None) -> None:
        state = self.tf_show()
        for g in state["values"]["root_module"]["child_modules"]:
            if g["address"].startswith("module.eotk_"):
                group_id = int(g["address"][len("module.eotk_"):])
                for i in g["child_modules"]:
                    if ".module.instance_" in i["address"]:
                        instance = int(i["address"][-1])
                        region = "us-east-2" if instance == 1 else "eu-central-1"
                        for s in i["child_modules"]:
                            if s["address"].endswith(".module.instance"):
                                for x in s["resources"]:
                                    if x["address"].endswith(".module.instance.aws_instance.default[0]"):
                                        update_eotk_instance(group_id, region, x['values']['id'])
        db.session.commit()
