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

class EKSAgent(BaseAgent):
    """
    An agent specialized in handling AWS Elastic Kubernetes Service (EKS) tasks.
    """

    def execute(self, command: str, **kwargs):
        """
        Executes a given command related to EKS.
        """
        if command == 'create_cluster':
            pass # Placeholder for code
        elif command == 'create_nodegroup':
            pass # Placeholder for code
        elif command == 'troubleshoot_cluster':
            return self._troubleshoot_cluster(**kwargs)
        else:
            raise NotImplementedError(f"Command '{command}' is not supported by EKSAgent.")

    def _create_cluster(self, region: str, name: str, role_arn: str, vpc_id: str, subnet_ids: list):
        # ... (code unchanged)
        pass

    def _create_nodegroup(self, region: str, cluster_name: str, nodegroup_name: str, node_role_arn: str, instance_types: list, subnet_ids: list):
        # ... (code unchanged)
        pass

    def _install_ebs_csi_driver(self, region: str, cluster_name: str):
        """
        Installs the Amazon EBS CSI driver as an EKS add-on.
        """
        print(f"EKSAgent: Installing EBS CSI driver for cluster '{cluster_name}'...")
        try:
            eks_client = AWSConnector.get_client('eks', region_name=region)
            iam_client = AWSConnector.get_client('iam', region_name=region)

            # 1. Create IAM Role for EBS CSI Driver
            ebs_csi_role_name = f'{cluster_name}-ebs-csi-role'
            cluster_oidc_issuer = eks_client.describe_cluster(name=cluster_name)["cluster"]["identity"]["oidc"]["issuer"]
            oidc_id = cluster_oidc_issuer.split('/')[-1]
            assume_role_policy_document = {
                "Version": "2012-10-17",
                "Statement": [
                    {
                        "Effect": "Allow",
                        "Principal": {
                            "Federated": f'arn:aws:iam::{AWSConnector.get_account_id()}:oidc-provider/oidc.eks.{region}.amazonaws.com/id/{oidc_id}'
                        },
                        "Action": "sts:AssumeRoleWithWebIdentity",
                        "Condition": {
                            "StringEquals": {
                                f'oidc.eks.{region}.amazonaws.com/id/{oidc_id}:aud': 'sts.amazonaws.com',
                                f'oidc.eks.{region}.amazonaws.com/id/{oidc_id}:sub': 'system:serviceaccount:kube-system:ebs-csi-controller-sa'
                            }
                        }
                    }
                ]
            }
            try:
                create_role_response = iam_client.create_role(
                    RoleName=ebs_csi_role_name,
                    AssumeRolePolicyDocument=json.dumps(assume_role_policy_document),
                    Description=f'IAM role for EKS EBS CSI driver on cluster {cluster_name}'
                )
                ebs_csi_role_arn = create_role_response['Role']['Arn']
                iam_client.attach_role_policy(
                    RoleName=ebs_csi_role_name,
                    PolicyArn='arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy'
                )
                print(f"Created IAM role for EBS CSI: {ebs_csi_role_arn} and attached policy.")
                time.sleep(10) # Give IAM time to propagate
            except iam_client.exceptions.EntityAlreadyExistsException:
                print(f"IAM role '{ebs_csi_role_name}' already exists. Fetching ARN...")
                ebs_csi_role_arn = iam_client.get_role(RoleName=ebs_csi_role_name)['Role']['Arn']

            # 2. Install EBS CSI Driver Add-on
            eks_client.create_addon(
                clusterName=cluster_name,
                addonName='aws-ebs-csi-driver',
                serviceAccountRoleArn=ebs_csi_role_arn
            )
            print("EBS CSI driver add-on creation initiated.")
            return {"status": "success", "message": "EBS CSI driver installation initiated."}
        except Exception as e:
            print(f"Error installing EBS CSI driver: {e}")
            return {"status": "error", "message": str(e)}

    def _install_efs_csi_driver(self, region: str, cluster_name: str):
        """
        Installs the Amazon EFS CSI driver as an EKS add-on.
        """
        print(f"EKSAgent: Installing EFS CSI driver for cluster '{cluster_name}'...")
        try:
            eks_client = AWSConnector.get_client('eks', region_name=region)
            iam_client = AWSConnector.get_client('iam', region_name=region)

            # 1. Create IAM Role for EFS CSI Driver
            efs_csi_role_name = f'{cluster_name}-efs-csi-role'
            cluster_oidc_issuer = eks_client.describe_cluster(name=cluster_name)["cluster"]["identity"]["oidc"]["issuer"]
            oidc_id = cluster_oidc_issuer.split('/')[-1]
            assume_role_policy_document = {
                "Version": "2012-10-17",
                "Statement": [
                    {
                        "Effect": "Allow",
                        "Principal": {
                            "Federated": f'arn:aws:iam::{AWSConnector.get_account_id()}:oidc-provider/oidc.eks.{region}.amazonaws.com/id/{oidc_id}'
                        },
                        "Action": "sts:AssumeRoleWithWebIdentity",
                        "Condition": {
                            "StringEquals": {
                                f'oidc.eks.{region}.amazonaws.com/id/{oidc_id}:aud': 'sts.amazonaws.com',
                                f'oidc.eks.{region}.amazonaws.com/id/{oidc_id}:sub': 'system:serviceaccount:kube-system:efs-csi-controller-sa'
                            }
                        }
                    }
                ]
            }
            try:
                create_role_response = iam_client.create_role(
                    RoleName=efs_csi_role_name,
                    AssumeRolePolicyDocument=json.dumps(assume_role_policy_document),
                    Description=f'IAM role for EKS EFS CSI driver on cluster {cluster_name}'
                )
                efs_csi_role_arn = create_role_response['Role']['Arn']
                iam_client.attach_role_policy(
                    RoleName=efs_csi_role_name,
                    PolicyArn='arn:aws:iam::aws:policy/service-role/AmazonEFSCSIDriverPolicy'
                )
                print(f"Created IAM role for EFS CSI: {efs_csi_role_arn} and attached policy.")
                time.sleep(10) # Give IAM time to propagate
            except iam_client.exceptions.EntityAlreadyExistsException:
                print(f"IAM role '{efs_csi_role_name}' already exists. Fetching ARN...")
                efs_csi_role_arn = iam_client.get_role(RoleName=efs_csi_role_name)['Role']['Arn']

            # 2. Install EFS CSI Driver Add-on
            eks_client.create_addon(
                clusterName=cluster_name,
                addonName='aws-efs-csi-driver',
                serviceAccountRoleArn=efs_csi_role_arn
            )
            print("EFS CSI driver add-on creation initiated.")
            return {"status": "success", "message": "EFS CSI driver installation initiated."}
        except Exception as e:
            print(f"Error installing EFS CSI driver: {e}")
            return {"status": "error", "message": str(e)}

    def _install_aws_load_balancer_controller(self, region: str, cluster_name: str, vpc_id: str):
        """
        Prepares for the installation of the AWS Load Balancer Controller.
        This involves creating the necessary IAM policy and role.
        Actual deployment of the controller (e.g., via Helm) is a manual step.
        """
        print(f"EKSAgent: Preparing for AWS Load Balancer Controller installation for cluster '{cluster_name}'...")
        try:
            iam_client = AWSConnector.get_client('iam', region_name=region)
            eks_client = AWSConnector.get_client('eks', region_name=region)

            # 1. Create IAM Policy for ALB Controller
            alb_policy_name = f'{cluster_name}-aws-load-balancer-controller-policy'
            alb_policy_document = {
                "Version": "2012-10-17",
                "Statement": [
                    {
                        "Effect": "Allow",
                        "Action": [
                            "iam:CreateServiceLinkedRole",
                            "ec2:DescribeAccountAttributes",
                            "ec2:DescribeAddresses",
                            "ec2:DescribeAvailabilityZones",
                            "ec2:DescribeInternetGateways",
                            "ec2:DescribeVpcs",
                            "ec2:DescribeSubnets",
                            "ec2:DescribeSecurityGroups",
                            "ec2:DescribeClassicLinkInstances",
                            "ec2:DescribeInstanceStatus",
                            "ec2:DescribeInstances",
                            "ec2:DescribeNetworkInterfaces",
                            "ec2:DescribeTags",
                            "ec2:GetCoipPoolUsage",
                            "ec2:DescribeCoipPools",
                            "elasticloadbalancing:DescribeLoadBalancers",
                            "elasticloadbalancing:DescribeLoadBalancerAttributes",
                            "elasticloadbalancing:DescribeListeners",
                            "elasticloadbalancing:DescribePredefinedPolicies",
                            "elasticloadbalancing:DescribeTargetGroups",
                            "elasticloadbalancing:DescribeTargetGroupAttributes",
                            "elasticloadbalancing:DescribeTags",
                            "elasticloadbalancing:DescribeTargetHealth",
                            "elasticloadbalancing:DescribeListenerCertificates",
                            "elasticloadbalancing:DescribeSSLPolicies"
                        ],
                        "Resource": "*"
                    },
                    {
                        "Effect": "Allow",
                        "Action": [
                            "ec2:AuthorizeSecurityGroupIngress",
                            "ec2:RevokeSecurityGroupIngress",
                            "ec2:CreateSecurityGroup",
                            "ec2:DeleteSecurityGroup"
                        ],
                        "Resource": "*"
                    },
                    {
                        "Effect": "Allow",
                        "Action": [
                            "ec2:CreateTags",
                            "ec2:DeleteTags"
                        ],
                        "Resource": "ec2:*:*",
                        "Condition": {
                            "StringEquals": {
                                "ec2:CreateAction": [
                                    "CreateSecurityGroup",
                                    "CreateTags"
                                ]
                            },
                            "ForAllValues:StringLike": {
                                "ec2:ResourceTag/elbv2.k8s.aws/cluster": [
                                    f"*{cluster_name}*"
                                ]
                            }
                        }
                    },
                    {
                        "Effect": "Allow",
                        "Action": [
                            "elasticloadbalancing:CreateLoadBalancer",
                            "elasticloadbalancing:CreateTargetGroup",
                            "elasticloadbalancing:CreateListener",
                            "elasticloadbalancing:CreateListenerCertificate",
                            "elasticloadbalancing:AddTags",
                            "elasticloadbalancing:RemoveTags",
                            "elasticloadbalancing:ModifyLoadBalancerAttributes",
                            "elasticloadbalancing:ModifyListener",
                            "elasticloadbalancing:ModifyTargetGroup",
                            "elasticloadbalancing:ModifyTargetGroupAttributes",
                            "elasticloadbalancing:SetWebAcl",
                            "elasticloadbalancing:SetSecurityGroups",
                            "elasticloadbalancing:SetSubnets",
                            "elasticloadbalancing:SetIpAddressType"
                        ],
                        "Resource": "*"
                    },
                    {
                        "Effect": "Allow",
                        "Action": [
                            "elasticloadbalancing:RegisterTargets",
                            "elasticloadbalancing:DeregisterTargets"
                        ],
                        "Resource": "*"
                    },
                    {
                        "Effect": "Allow",
                        "Action": [
                            "elasticloadbalancing:DeleteLoadBalancer",
                            "elasticloadbalancing:DeleteTargetGroup",
                            "elasticloadbalancing:DeleteListener",
                            "elasticloadbalancing:DeleteListenerCertificate"
                        ],
                        "Resource": "*"
                    }
                ]
            }

            try:
                create_policy_response = iam_client.create_policy(
                    PolicyName=alb_policy_name,
                    PolicyDocument=json.dumps(alb_policy_document),
                    Description=f'IAM policy for AWS Load Balancer Controller on EKS cluster {cluster_name}'
                )
                alb_policy_arn = create_policy_response['Policy']['Arn']
                print(f"Created IAM policy for ALB Controller: {alb_policy_arn}")
            except iam_client.exceptions.EntityAlreadyExistsException:
                print(f"IAM policy '{alb_policy_name}' already exists. Fetching ARN...")
                alb_policy_arn = iam_client.get_policy(PolicyArn=f'arn:aws:iam::{AWSConnector.get_account_id()}:policy/{alb_policy_name}')['Policy']['Arn']

            # 2. Create IAM Role for ALB Controller Service Account
            alb_role_name = f'{cluster_name}-aws-load-balancer-controller-role'
            oidc_issuer = eks_client.describe_cluster(name=cluster_name)['cluster']['identity']['oidc']['issuer'].split('/')[-1]
            assume_role_policy_document_sa = {
                "Version": "2012-10-17",
                "Statement": [
                    {
                        "Effect": "Allow",
                        "Principal": {
                            "Federated": f'arn:aws:iam::{AWSConnector.get_account_id()}:oidc-provider/oidc.eks.{region}.amazonaws.com/id/{oidc_issuer}'
                        },
                        "Action": "sts:AssumeRoleWithWebIdentity",
                        "Condition": {
                            "StringEquals": {
                                f'oidc.eks.{region}.amazonaws.com/id/{oidc_issuer}:aud': 'sts.amazonaws.com',
                                f'oidc.eks.{region}.amazonaws.com/id/{oidc_issuer}:sub': 'system:serviceaccount:kube-system:aws-load-balancer-controller'
                            }
                        }
                    }
                ]
            }
            try:
                create_role_response = iam_client.create_role(
                    RoleName=alb_role_name,
                    AssumeRolePolicyDocument=json.dumps(assume_role_policy_document_sa),
                    Description=f'IAM role for AWS Load Balancer Controller service account on cluster {cluster_name}'
                )
                alb_role_arn = create_role_response['Role']['Arn']
                iam_client.attach_role_policy(
                    RoleName=alb_role_name,
                    PolicyArn=alb_policy_arn
                )
                print(f"Created IAM role for ALB Controller service account: {alb_role_arn} and attached policy.")
                time.sleep(10) # Give IAM time to propagate
            except iam_client.exceptions.EntityAlreadyExistsException:
                print(f"IAM role '{alb_role_name}' already exists. Fetching ARN...")
                alb_role_arn = iam_client.get_role(RoleName=alb_role_name)['Role']['Arn']

            return {"status": "success", "message": "IAM roles and policies for AWS Load Balancer Controller created. Please deploy the controller using Helm or kubectl.", "alb_controller_role_arn": alb_role_arn}
        except Exception as e:
            print(f"Error preparing for ALB Controller installation: {e}")
            return {"status": "error", "message": str(e)}

    def _troubleshoot_cluster(self, region: str, name: str):
        """Runs a series of diagnostic checks on an EKS cluster and its components."""
        print(f"EKSAgent: Troubleshooting cluster '{name}' in region {region}...")
        report = {
            'cluster_name': name,
            'region': region,
            'findings': [],
            'recommendations': []
        }
        try:
            eks_client = AWSConnector.get_client('eks', region_name=region)

            # 1. Describe Cluster
            cluster_desc = eks_client.describe_cluster(name=name)['cluster']
            report['findings'].append(f"Cluster status is '{cluster_desc['status']}'.")
            if cluster_desc['status'] != 'ACTIVE':
                report['recommendations'].append("Cluster is not in ACTIVE state. Check EKS console for creation errors.")
                return {"status": "success", "report": report}

            # 2. List and Describe Nodegroups
            nodegroups = eks_client.list_nodegroups(clusterName=name).get('nodegroups', [])
            if not nodegroups:
                report['findings'].append("No nodegroups found for this cluster.")
                report['recommendations'].append("Create a nodegroup to provide compute capacity.")
            
            for ng_name in nodegroups:
                ng_desc = eks_client.describe_nodegroup(clusterName=name, nodegroupName=ng_name)['nodegroup']
                report['findings'].append(f"Nodegroup '{ng_name}' status is '{ng_desc['status']}'.")
                if ng_desc['status'] != 'ACTIVE':
                    report['recommendations'].append(f"Nodegroup '{ng_name}' is not ACTIVE. Check its health issues.")
                if 'health' in ng_desc and ng_desc['health']['issues']:
                    report['findings'].append(f"Nodegroup '{ng_name}' has health issues: {ng_desc['health']['issues']}")
                    report['recommendations'].append("Resolve nodegroup health issues by checking the instance status and IAM role permissions.")

            return {"status": "success", "report": report}
        except Exception as e:
            print(f"Error during EKS troubleshooting: {e}")
            return {"status": "error", "message": str(e)}
