from .base_agent import BaseAgent
from ..aws_connector import AWSConnector
import time
import json

class FargateAgent(BaseAgent):
    """
    An agent specialized in handling AWS Fargate tasks (via ECS).
    """

    def execute(self, command: str, **kwargs):
        """
        Executes a given command related to Fargate.
        """
        if command == 'smart_deploy_container_app':
            app_name = kwargs.get('app_name', '')
            region = kwargs.get('region', '')
            print(f"You are about to smart-deploy a containerized application '{app_name}' to ECS Fargate in {region}.")
            confirm = input("This will create an ECS Cluster, Task Definition, and Service. It may also create a VPC and Security Group. Are you sure you want to proceed? (yes/no): ")
            if confirm.lower() == 'yes':
                return self._smart_deploy_container_app(**kwargs)
            else:
                return {"status": "cancelled", "message": "Smart Deploy Fargate container app command cancelled by user."}
        else:
            raise NotImplementedError(f"Command '{command}' is not supported by FargateAgent.")

    def _smart_deploy_container_app(self, region: str, app_name: str, vpc_id: str = None, subnet_ids: list = None, container_image: str = 'nginx:latest', container_port: int = 80, cpu: int = 256, memory: int = 512):
        """
        Deploys a simple containerized application to ECS Fargate.
        Creates an ECS cluster, a task definition, and a service.
        Automatically handles VPC and subnet creation if not provided.
        """
        print(f"FargateAgent: Smart deploying container app '{app_name}' to ECS Fargate in region {region}...")
        try:
            ecs_client = AWSConnector.get_client('ecs', region_name=region)
            iam_client = AWSConnector.get_client('iam', region_name=region)
            ec2_client = AWSConnector.get_client('ec2', region_name=region)

            # 1. Determine VPC and Subnets
            if vpc_id is None or subnet_ids is None:
                print("VPC ID or Subnet IDs not provided. Attempting to find/create VPC...")
                # Instantiate AgentManager to use VPC workflow
                agent_manager = AgentManager() 
                vpc_result = agent_manager._workflow_smart_create_vpc(region=region, name=f'{app_name}-fargate-vpc')
                if vpc_result['status'] != 'success':
                    return vpc_result
                vpc_id = vpc_result['outputs']['vpc_id']
                subnet_ids = [vpc_result['outputs']['public_subnet_id'], vpc_result['outputs']['private_subnet_id']]
                print(f"Using VPC: {vpc_id} with subnets: {subnet_ids}")

            # 2. Create ECS Cluster
            cluster_name = f'{app_name}-cluster'
            try:
                ecs_client.create_cluster(clusterName=cluster_name)
                print(f"ECS Cluster '{cluster_name}' created.")
            except ecs_client.exceptions.ClientException as e:
                if 'already exists' in str(e):
                    print(f"ECS Cluster '{cluster_name}' already exists. Using existing.")
                else:
                    raise

            # 3. Create Task Execution IAM Role
            task_execution_role_name = f'{app_name}-ecs-task-execution-role'
            assume_role_policy_document = {
                "Version": "2012-10-17",
                "Statement": [
                    {
                        "Effect": "Allow",
                        "Principal": {
                            "Service": "ecs-tasks.amazonaws.com"
                        },
                        "Action": "sts:AssumeRole"
                    }
                ]
            }
            try:
                create_role_response = iam_client.create_role(
                    RoleName=task_execution_role_name,
                    AssumeRolePolicyDocument=json.dumps(assume_role_policy_document),
                    Description=f'ECS Task Execution role for {app_name}'
                )
                task_execution_role_arn = create_role_response['Role']['Arn']
                iam_client.attach_role_policy(
                    RoleName=task_execution_role_name,
                    PolicyArn='arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy'
                )
                print(f"Created IAM role: {task_execution_role_arn} and attached policy.")
                time.sleep(10)  # Give IAM time to propagate
            except iam_client.exceptions.EntityAlreadyExistsException:
                print(f"IAM role '{task_execution_role_name}' already exists. Fetching ARN...")
                task_execution_role_arn = iam_client.get_role(RoleName=task_execution_role_name)['Role']['Arn']

            # 4. Create Task Definition
            task_definition_name = f'{app_name}-task-def'
            register_task_response = ecs_client.register_task_definition(
                Family=task_definition_name,
                NetworkMode='awsvpc',
                RequiresCompatibilities=['FARGATE'],
                Cpu=str(cpu),
                Memory=str(memory),
                ExecutionRoleArn=task_execution_role_arn,
                ContainerDefintions=[
                    {
                        'name': f'{app_name}-container',
                        'image': container_image,
                        'portMappings': [
                            {
                                'containerPort': container_port,
                                'hostPort': container_port,
                                'protocol': 'tcp'
                            },
                        ],
                        'essential': True
                    }
                ]
            )
            task_definition_arn = register_task_response['taskDefinition']['taskDefinitionArn']
            print(f"Task Definition '{task_definition_name}' registered.")

            # 5. Create Security Group for Fargate Service (if not provided -- simplified for now)
            sg_name = f'{app_name}-fargate-sg'
            sg_description = f'Security group for Fargate service {app_name}'
            try:
                sg_response = ec2_client.create_security_group(GroupName=sg_name, Description=sg_description, VpcId=vpc_id)
                security_group_id = sg_response['GroupId']
                ec2_client.authorize_security_group_ingress(
                    GroupId=security_group_id,
                    IpPermissions=[
                        {'IpProtocol': 'tcp', 'FromPort': container_port, 'ToPort': container_port, 'IpRanges': [{'CidrIp': '0.0.0.0/0'}]} # Allow traffic to container port
                    ]
                )
                print(f"Created Security Group: {security_group_id}")
            except ec2_client.exceptions.ClientError as e:
                if 'already exists' in str(e):
                    print(f"Security Group '{sg_name}' already exists. Attempting to use existing.")
                    sg_details = ec2_client.describe_security_groups(Filters=[{'Name': 'group-name', 'Values': [sg_name]}, {'Name': 'vpc-id', 'Values': [vpc_id]}]).get('SecurityGroups', [])
                    if sg_details:
                        security_group_id = sg_details[0]['GroupId']
                    else:
                        raise Exception(f"Could not find existing security group '{sg_name}'.")
                else:
                    raise

            # 6. Create ECS Service
            service_name = f'{app_name}-service'
            create_service_response = ecs_client.create_service(
                Cluster=cluster_name,
                ServiceName=service_name,
                TaskDefinition=task_definition_arn,
                DesiredCount=1,
                LaunchType='FARGATE',
                NetworkConfiguration={
                    'awsvpcConfiguration': {
                        'subnets': subnet_ids,
                        'securityGroups': [security_group_id],
                        'assignPublicIp': 'ENABLED'
                    }
                }
            )
            service_arn = create_service_response['service']['serviceArn']
            print(f"ECS Service '{service_name}' created.")

            return {"status": "success", "message": f"Fargate container app '{app_name}' deployed successfully.", "cluster_arn": cluster_name, "service_arn": service_arn, "task_definition_arn": task_definition_arn, "vpc_id": vpc_id, "subnet_ids": subnet_ids, "security_group_id": security_group_id}
        except Exception as e:
            print(f"Error during smart Fargate container app deployment: {e}")
            return {"status": "error", "message": str(e)}
