module "default_tags" {
  source             = "git@github.com:theorchard/terraform-default-tags.git//?ref=1.0.0"
  environment        = var.environment
  application_family = var.application_family
  service_name       = var.service_name
}

provider "aws" {
  region = var.aws_region

  default_tags {
    tags = module.default_tags.tags
  }
}

terraform {
  backend "s3" {
    bucket  = "qa-test-automation-pde-terraform-state"
    key     = "qa/cypress-worker/terraform.tfstate"
    region  = "us-east-1"
    encrypt = "true"
  }
}

data "aws_caller_identity" "current" {}

module "vpc_info" {
  source = "git@github.com:theorchard/terraform-vpc-info.git//?ref=3.1.0"

  environment = var.environment
}

module "s3_bucket" {
  source = "git@github.com:theorchard/terraform-s3.git//modules/s3_bucket?ref=3.12.1"

  env                 = var.environment
  bucket_name         = var.config_s3_bucket_name
  application_family  = var.application_family
  s3_read_only_policy = false
  block_public_access = true

  apply_server_side_encryption_by_default = {
    sse_algorithm = "AES256"
  }

  lifecycle_rules_options_current_version_expiration = [
    {
      prefix  = "results"
      enabled = true
      days    = 7
    },
    {
      prefix  = "testerloop-results"
      enabled = true
      days    = 7
    }
  ]

  lifecycle_rules_options_noncurrent_version_expiration = [
    {
      prefix  = ""
      enabled = true
      days    = 7
    }
  ]
}

data "aws_iam_policy_document" "cypress_worker_task_policy" {
  statement {
    actions = [
      "ec2:DescribeSecurityGroups",
      "ecs:DescribeClusters",
      "ecs:DescribeTasks",
      "ecs:DescribeTaskDefinition",
      "ecs:ListTasks",
      "ecs:ListTaskDefinitions",
    ]
    effect = "Allow"

    resources = [
      "*",
    ]
  }

  statement {
    actions = [
      "ecs:RunTask",
      "ecs:StartTask",
    ]

    resources = [
      "arn:aws:ecs:*:${data.aws_caller_identity.current.account_id}:cluster/${var.environment}-${var.service_name}",
      "arn:aws:ecs:*:${data.aws_caller_identity.current.account_id}:task-definition/${var.environment}-${var.service_name}:*"
    ]
  }

  statement {
    actions = [
      "iam:PassRole",
    ]
    effect = "Allow"
    resources = [
      "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${var.environment}-${var.service_name}-role",
      "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${var.environment}-${var.service_name}-task-execution-role*",
      "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${var.environment}-${var.service_name}-task-role"
    ]
  }
}

resource "aws_iam_policy" "cypress_worker_fargate_tasks_policy" {
  name   = "Task-${var.environment}-${var.service_name}-run-task-policy"
  policy = data.aws_iam_policy_document.cypress_worker_task_policy.json

  tags = {
    environment        = var.environment
    terraformed        = "true"
    application_family = var.application_family
  }
}

resource "aws_iam_role_policy_attachment" "cypress_worker_fargate_tasks_policy_attachment" {
  role       = aws_iam_role.cypress_worker_role.name
  policy_arn = aws_iam_policy.cypress_worker_fargate_tasks_policy.arn
}

# Cross-account IAM role will be used to access PROD AWS Account S3 buckets
# data "aws_iam_policy_document" "cypress_worker_s3_bucket_policy_document" {
#   statement {
#     effect = "Allow"
#     actions = [
#       "s3:GetBucketLocation",
#       "s3:GetObject*",
#       "s3:ListBucket",
#       "s3:PutObject*",
#     ]
#     resources = [
#       "arn:aws:s3:::${var.environment}-neighbouring-rights",
#       "arn:aws:s3:::${var.environment}-neighbouring-rights/*",
#       "arn:aws:s3:::${var.environment}-encoding-direct-delivery-physical-location-9",
#       "arn:aws:s3:::${var.environment}-encoding-direct-delivery-physical-location-9/*",
#       "arn:aws:s3:::${var.environment}-orcdbucket",
#       "arn:aws:s3:::${var.environment}-orcdbucket/qa-statement-attachments",
#       "arn:aws:s3:::${var.environment}-orcdbucket/qa-statement-attachments/*",
#       "arn:aws:s3:::${var.environment}-statement-detail-exports",
#       "arn:aws:s3:::${var.environment}-statement-detail-exports/*",
#       "arn:aws:s3:::${var.environment}-orcdbucket/qa-per-label-statement-attachments",
#       "arn:aws:s3:::${var.environment}-orcdbucket/qa-per-label-statement-attachments/*",
#       "arn:aws:s3:::prod-orcd-ftp",
#       "arn:aws:s3:::prod-orcd-ftp/ftp/qa_vector_test/*",
#       "arn:aws:s3:::qa-orcd-raw-assets",
#       "arn:aws:s3:::qa-orcd-raw-assets/*",
#     ]
#   }
#   statement {
#     effect = "Allow"
#     actions = [
#       "s3:DeleteObject",
#       "s3:DeleteObject*"
#     ]
#     resources = [
#       "arn:aws:s3:::${var.environment}-neighbouring-rights/contributions/*",
#       "arn:aws:s3:::${var.environment}-encoding-direct-delivery-physical-location-9/*",
#       "arn:aws:s3:::${var.environment}-orcdbucket/qa-statement-attachments/*",
#     ]
#   }
# }

data "aws_iam_policy_document" "cypress_worker_assume_role_policy_document" {
  statement {
    actions = ["sts:AssumeRole"]

    principals {
      type = "AWS"

      identifiers = [
        "arn:aws:iam::437795906767:role/prod-jenkins-aws-pipeline-agent",
      ]
    }
  }
}

resource "aws_iam_role" "cypress_worker_role" {
  name               = "${var.environment}-cypress-worker-role"
  assume_role_policy = data.aws_iam_policy_document.cypress_worker_assume_role_policy_document.json
  tags = {
    environment        = var.environment
    terraformed        = "true"
    application_family = var.application_family
  }
}

data "aws_iam_policy_document" "cypress_worker_s3_config_bucket_policy_document" {
  statement {
    effect = "Allow"
    actions = [
      "s3:GetBucketLocation",
      "s3:GetObject*",
      "s3:ListBucket",
      "s3:PutObject*",
      "s3:DeleteObject",
      "s3:DeleteObject*"
    ]
    resources = [
      module.s3_bucket.s3_bucket_arn_output,
      "${module.s3_bucket.s3_bucket_arn_output}/*",
    ]
  }
}

data "aws_iam_policy_document" "cypress_worker_secrets_manager_policy" {
  statement {
    actions = [
      "secretsmanager:GetResourcePolicy",
      "secretsmanager:GetSecretValue",
      "secretsmanager:DescribeSecret",
      "secretsmanager:ListSecretVersionIds",
    ]

    resources = [
      "arn:aws:secretsmanager:*:*:secret:${var.environment}/cypress-configs/",
      "arn:aws:secretsmanager:*:*:secret:${var.environment}/cypress-configs/*",
    ]
  }

  statement {
    actions = [
      "secretsmanager:GetRandomPassword",
    ]

    resources = [
      "*",
    ]
  }
}

# Cross-account IAM role will be used to access PROD AWS Account dynamoDB
# data "aws_iam_policy_document" "cypress_dynamoDb_policy_document" {
#   statement {
#     effect = "Allow"
#     actions = [
#       "dynamodb:Query",
#       "dynamodb:Scan",
#       "dynamodb:DeleteItem",
#     ]

#     resources = [
#       "arn:aws:dynamodb:us-east-1:437795906767:table/qa_statement_attachments_success",
#       "arn:aws:dynamodb:us-east-1:437795906767:table/qa-accounting-statement-export",
#       "arn:aws:dynamodb:us-east-1:437795906767:table/qa_statement_attachments_error",
#       "arn:aws:dynamodb:us-east-1:437795906767:table/ows-accounting-owsrequest"
#     ]
#   }
# }

# Cross-account IAM role will be used to access Supply Chain AWS Account lambda
# data "aws_lambda_function" "lambda-vector-ready-deliveries" {
#   function_name = "${var.environment}-lambda-vector-ready-deliveries"
# }

# data "aws_lambda_function" "lambda-vector-renew" {
#   function_name = "${var.environment}-lambda-vector-renew"
# }

# data "aws_lambda_function" "lambda-vector-throttler" {
#   function_name = "${var.environment}-lambda-vector-throttler"
# }

# data "aws_iam_policy_document" "cypress_lambda_access_policy_document" {
#   statement {
#     effect = "Allow"
#     actions = [
#       "lambda:InvokeFunction",
#     ]
#     resources = [
#       data.aws_lambda_function.lambda-vector-ready-deliveries.arn,
#       data.aws_lambda_function.lambda-vector-renew.arn,
#       data.aws_lambda_function.lambda-vector-throttler.arn,
#     ]
#   }
# }

# resource "aws_iam_policy" "cypress_dynamoDb_policy" {
#   name   = "DynamoDb-${var.environment}-${var.service_name}-read-write-policy"
#   policy = data.aws_iam_policy_document.cypress_dynamoDb_policy_document.json

#   tags = {
#     terraformed        = true
#     application_family = var.application_family
#   }
# }

# resource "aws_iam_policy" "cypress_lambda_policy" {
#   name   = "${var.environment}-${var.service_name}-lambda-access-policy"
#   policy = data.aws_iam_policy_document.cypress_lambda_access_policy_document.json

#   tags = {
#     terraformed        = true
#     application_family = var.application_family
#   }
# }


# We should avoid using IAM user for this service.
# Create IAM group cypress-worker.
# resource "aws_iam_group" "cypress_worker_iam_group" {
#   name = "cypress-worker"
# }

# Reuse IAM cucumber-tests user.
# resource "aws_iam_group_membership" "cypress_worker_iam_group_membership" {
#   name = "cypress_worker_iam_group_membership"
#   users = [
#     "cucumber-tests",
#   ]

#   group = aws_iam_group.cypress_worker_iam_group.name
# }

# resource "aws_iam_group_policy_attachment" "iam_group_policy_attachment" {
#   for_each = toset([
#     "arn:aws:iam::${data.aws_caller_identity.current.account_id}:policy/S3-config-${var.environment}-${var.service_name}-read-write-policy",
#     "arn:aws:iam::${data.aws_caller_identity.current.account_id}:policy/Secretsmanager-${var.environment}-${var.service_name}-secrets-manager-policy",
#     "arn:aws:iam::${data.aws_caller_identity.current.account_id}:policy/Task-${var.environment}-${var.service_name}-run-task-policy",
#   ])

#   policy_arn = each.value
#   group      = aws_iam_group.cypress_worker_iam_group.name
# }

# Create secrets manager policy for cypress-configs
resource "aws_iam_policy" "cypress_worker_secrets_manager_policy" {
  name   = "Secretsmanager-${var.environment}-${var.service_name}-secrets-manager-policy"
  policy = data.aws_iam_policy_document.cypress_worker_secrets_manager_policy.json

  tags = {
    terraformed        = true
    application_family = var.application_family
  }
}

resource "aws_iam_policy" "s3_config_cypress_worker_read_write_policy" {
  name   = "S3-config-${var.environment}-${var.service_name}-read-write-policy"
  policy = data.aws_iam_policy_document.cypress_worker_s3_config_bucket_policy_document.json

  tags = {
    terraformed        = true
    application_family = var.application_family
  }
}

module "cypress_secrets" {
  source   = "git@github.com:theorchard/terraform-secrets-manager.git//?ref=1.5.1"
  for_each = toset(var.secrets_manager_secret_names)

  environment                    = var.environment
  service_name                   = "cypress-configs"
  secret_name                    = each.value
  application_family             = "cypress"
  secret_recovery_window_in_days = 7
}

module "cypress_worker_fargate_environment" {
  source = "git@github.com:theorchard/terraform-fargate.git//?ref=5.6.1"

  providers = {
    aws.dns = aws
  }

  environment          = var.environment
  service_name         = var.service_name
  aws_region           = var.aws_region
  commit_sha           = "latest"
  container_port       = 9000
  task_type            = "worker"
  desired_task_count   = 0
  task_cpu             = 4096
  task_memory          = 12288
  maximum_capacity     = 200
  minimum_capacity     = 0
  vpc_id               = module.vpc_info.vpc_id
  application_family   = var.application_family
  health_check_command = "$(npm bin)/cypress verify"

  iam_managed_policy_attachments = [
    aws_iam_policy.cypress_worker_secrets_manager_policy.arn,
    aws_iam_policy.s3_config_cypress_worker_read_write_policy.arn,
    aws_iam_policy.cypress_worker_fargate_tasks_policy.arn,
  ]

  fargate_service_subnets = module.vpc_info.default_private_subnet_ids

  environment_variables = [
    {
      Environment = var.environment
    },
    {
      LOGGER_DSN = "https://${var.environment}-fluentd-applications.theorchard.io:8888/application"
    },
  ]
}

module "cypress_worker_fargate_service_dashboard" {
  source = "git@github.com:theorchard/terraform-datadog.git//modules/service?ref=6.13.4"

  environment                       = var.environment
  environment_type                  = "fargate"
  service_name                      = var.service_name
  service_4xx_monitor_enabled       = false
  service_5xx_monitor_enabled       = false
  notification_endpoints            = "@slack-cucumber-cypress-development"
  escalation_notification_endpoints = "@slack-cucumber-cypress-development"
  application_family                = var.application_family
}
