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

provider "aws" {
  region = var.region

  default_tags {
    tags = module.default_tags.tags
  }
}

provider "aws" {
  region  = var.region
  alias   = "networking"
  profile = "networking"

  default_tags {
    tags = module.default_tags.tags
  }
}

terraform {
  backend "s3" {
    bucket  = "orcd-terraform-state"
    key     = "prod/distribution/distro-scripts/dolby-atmos-packager-alpha/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 "input_s3_bucket" {
  source = "git@github.com:theorchard/terraform-s3.git//modules/s3_bucket?ref=3.15.2"

  bucket_name        = "${var.service_name}-input"
  env                = var.environment
  application_family = var.application_family

  apply_server_side_encryption_by_default = {
    sse_algorithm = "AES256"
  }

  lifecycle_rules_options_current_version_transition = [
    {
      prefix        = ""
      enabled       = true
      days          = 0
      storage_class = "INTELLIGENT_TIERING"
    }
  ]
}

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

  bucket_name        = "${var.service_name}-output"
  env                = var.environment
  application_family = var.application_family

  apply_server_side_encryption_by_default = {
    sse_algorithm = "AES256"
  }

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

  lifecycle_rules_options_current_version_expiration = [
    {
      prefix  = ""
      enabled = true
      days    = 30
    },
  ]

  lifecycle_rules_expired_object_delete_markers_expiration = [
    {
      prefix  = ""
      enabled = true
    },
  ]

  lifecycle_rules_options_current_version_transition = [
    {
      prefix        = ""
      enabled       = true
      days          = 0
      storage_class = "INTELLIGENT_TIERING"
    }
  ]
}

data "aws_iam_policy_document" "s3_access_policy" {
  statement {
    effect = "Allow"

    actions = [
      "s3:ListBucket"
    ]

    resources = [
      module.input_s3_bucket.s3_bucket_arn_output,
      module.output_s3_bucket.s3_bucket_arn_output
    ]
  }

  statement {
    effect = "Allow"

    actions = [
      "s3:PutObject",
      "s3:HeadObject",
      "s3:GetObject"
    ]

    resources = [
      "${module.input_s3_bucket.s3_bucket_arn_output}/*",
      "${module.output_s3_bucket.s3_bucket_arn_output}/*"
    ]
  }
}

resource "aws_iam_policy" "s3_access_policy" {
  name        = "S3-${var.environment}-${var.service_name}-RW"
  description = "Read and write to ${var.service_name} buckets"
  policy      = data.aws_iam_policy_document.s3_access_policy.json
}

module "dolby_atmos_packager_alpha_sentry_project" {
  source = "git@github.com:theorchard/terraform-sentry.git//?ref=4.1.2"

  service_name       = var.service_name
  environment        = var.environment
  teams              = [var.environment]
  application_family = var.application_family
  platform           = "python"
}

module "dolby_atmos_packager_alpha_owsrequest" {
  source = "git@github.com:theorchard/terraform-owsrequest.git//?ref=1.1.0"

  environment_name = var.environment
  service_name     = var.service_name
}

data "aws_iam_policy" "s3_mezz_ro" {
  name = "S3-${var.environment}-orcd-mezzanine-assets-RO"
}

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

  providers = {
    aws.dns = aws.networking
  }

  environment        = var.environment
  service_name       = var.service_name
  application_family = var.application_family
  aws_region         = var.region
  commit_sha         = "latest"

  autoscaling_cpu_policy_enabled = false

  task_type            = "worker"
  health_check_command = "python --version"
  desired_task_count   = 0
  task_cpu             = 1024
  task_memory          = 2048
  maximum_capacity     = 5
  minimum_capacity     = 0
  datadog_enabled      = true

  vpc_id                  = module.vpc_info.vpc_id
  fargate_service_subnets = module.vpc_info.default_private_subnet_ids

  splitio_enabled                 = false
  ows_machine_to_machine_enabled  = true
  stopped_task_monitoring_enabled = false

  iam_managed_policy_attachments = [
    aws_iam_policy.s3_access_policy.arn,
    module.dolby_atmos_packager_alpha_owsrequest.policy_arn_output,
    data.aws_iam_policy.s3_mezz_ro.arn
  ]

  environment_variables = [
    {
      Environment = var.environment
    },
    {
      INPUT_BUCKET = module.input_s3_bucket.s3_bucket_name_output
    },
    {
      OUTPUT_BUCKET = module.output_s3_bucket.s3_bucket_name_output
    },
    {
      USER_IDENTITY_ID = var.user_identity_id
    },
    {
      USER_IDENTITY_UUID = var.user_identity_uuid
    },
    {
      USER_PROFILE_ID = var.user_profile_id
    },
    {
      USER_PROFILE_UUID = var.user_profile_uuid
    },
    {
      USER_PROFILE_TYPE = var.user_profile_type
    },
    {
      USER_ROLES = var.user_roles
    }
  ]

  secrets = [
    {
      SENTRY_DSN = "${var.environment}/${var.service_name}/SENTRY_DSN"
    }
  ]
}

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

    principals {
      type = "AWS"

      identifiers = [
        "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/prod-jenkins-aws-task-agent",
      ]
    }
  }
}

data "aws_iam_policy_document" "run_task_policy_document" {
  statement {
    effect = "Allow"
    actions = [
      "ec2:DescribeSecurityGroups",
      "ec2:DescribeSubnets",
      "ec2:DescribeVpcs",
      "ecs:DescribeTasks"
    ]
    resources = ["*"]
  }

  statement {
    effect = "Allow"
    actions = [
      "ecs:RunTask",
      "ecs:StartTask"
    ]
    resources = [
      "${module.dolby_atmos_packager_alpha_fargate.fargate_task_definition_arn_without_revision}:*",
      module.dolby_atmos_packager_alpha_fargate.fargate_cluster_arn
    ]
  }

  statement {
    effect = "Allow"
    actions = [
      "ecs:TagResource",
    ]
    resources = ["*"]
    condition {
      test     = "StringEquals"
      variable = "ecs:CreateAction"
      values = [
        "RunTask",
        "StartTask",
      ]
    }
  }

  statement {
    effect  = "Allow"
    actions = ["iam:PassRole"]
    condition {
      test     = "StringLike"
      variable = "iam:PassedToService"
      values   = ["ecs-tasks.amazonaws.com"]
    }
    resources = [
      module.dolby_atmos_packager_alpha_fargate.fargate_task_iam_role_arn,
      module.dolby_atmos_packager_alpha_fargate.fargate_task_iam_execution_role_arn
    ]
  }
}

resource "aws_iam_role" "jenkins_run_role" {
  name                  = "${var.environment}-${var.service_name}-jenkins-run-role"
  force_detach_policies = true
  assume_role_policy    = data.aws_iam_policy_document.assume_role_policy_document.json

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

resource "aws_iam_policy" "jenkins_run_policy" {
  name   = "${var.environment}-${var.service_name}-run-policy"
  policy = data.aws_iam_policy_document.run_task_policy_document.json

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

resource "aws_iam_role_policy_attachment" "jenkins_run_policy_attachment" {
  role       = aws_iam_role.jenkins_run_role.id
  policy_arn = aws_iam_policy.jenkins_run_policy.arn
}

data "aws_iam_policy_document" "dolby_atmos_packager_alpha_input_permissions" {
  statement {
    sid = "AllowUserToSeeBucketList"
    actions = [
      "s3:ListAllMyBuckets",
    ]
    effect    = "Allow"
    resources = ["*"]
  }

  statement {
    effect = "Allow"

    actions = [
      "s3:PutObject",
      "s3:DeleteObject",
      "s3:GetObject*",
      "s3:ListBucket*",
      "s3:ListMultipartUploadParts"
    ]

    resources = [
      "${module.input_s3_bucket.s3_bucket_arn_output}/*"
    ]
  }

  statement {
    effect = "Allow"

    actions = [
      "s3:ListBucket",
      "s3:ListBucketVersions",
      "s3:GetBucketLocation",
      "s3:GetBucketVersioning",
    ]

    resources = [
      module.input_s3_bucket.s3_bucket_arn_output
    ]

  }
}

resource "aws_iam_policy" "dolby_atmos_packager_alpha_input_policy" {
  name        = "${var.environment}-dolby-atmos-packager-alpha-input-policy"
  policy      = data.aws_iam_policy_document.dolby_atmos_packager_alpha_input_permissions.json
  description = "Provides granular upload access to dolby atmos packager alpha input bucket."
}

data "aws_iam_policy_document" "dolby_atmos_packager_alpha_output_permissions" {
  statement {
    sid = "AllowUserToSeeBucketList"
    actions = [
      "s3:ListAllMyBuckets",
    ]
    effect    = "Allow"
    resources = ["*"]
  }

  statement {
    effect = "Allow"

    actions = [
      "s3:GetObject*",
      "s3:ListBucket*",
      "s3:ListMultipartUploadParts"
    ]

    resources = [
      "${module.output_s3_bucket.s3_bucket_arn_output}/*"
    ]
  }

  statement {
    effect = "Allow"

    actions = [
      "s3:ListBucket",
      "s3:ListBucketVersions",
      "s3:GetBucketLocation",
      "s3:GetBucketVersioning",
    ]

    resources = [
      module.output_s3_bucket.s3_bucket_arn_output
    ]

  }
}

resource "aws_iam_policy" "dolby_atmos_packager_alpha_output_policy" {
  name        = "${var.environment}-dolby-atmos-packager-alpha-output-policy"
  policy      = data.aws_iam_policy_document.dolby_atmos_packager_alpha_output_permissions.json
  description = "Provides granular upload access to dolby atmos packager alpha output bucket."
}

resource "aws_iam_group" "dolby_atmos_packager_alpha_managers" {
  name = "${var.environment}-dolby-atmos-packager-alpha-manager"
}

resource "aws_iam_group_membership" "dolby_atmos_packager_alpha_membership" {
  name = "dolby-atmos-packager-alpha-membership"

  users = [
    "acentenorodriguez",
    "astephenson",
    "ccesaro",
    "cking",
    "ffunigiello",
    "gmcclellan",
    "hsanthalingam",
    "jbarcella",
    "jblancas",
    "mberns",
    "mnigro",
    "mrawat",
    "mstyles",
    "mzambranagarcia",
    "nnorthrup",
    "rthirunavukkarasu",
    "shenderson",
    "jjeyakumar",
    "kravi",
    "bprithiviraj",
    "sbanu",
    "sbalasubramaniyan",
    "tasifalikhan",
    "ssrinivasan",
    "dirigoin",
  ]

  group = aws_iam_group.dolby_atmos_packager_alpha_managers.name
}

resource "aws_iam_group_policy_attachment" "dolby_atmos_packager_alpha_managers_input_iam_policy_attachment" {
  group      = aws_iam_group.dolby_atmos_packager_alpha_managers.name
  policy_arn = aws_iam_policy.dolby_atmos_packager_alpha_input_policy.arn
}

resource "aws_iam_group_policy_attachment" "dolby_atmos_packager_alpha_managers_output_iam_policy_attachment" {
  group      = aws_iam_group.dolby_atmos_packager_alpha_managers.name
  policy_arn = aws_iam_policy.dolby_atmos_packager_alpha_output_policy.arn
}

resource "aws_iam_user" "upload_access_user" {
  name = "${var.environment}-${var.service_name}-upload"

  tags = {
    terraformed = true
    role        = "service-user"
  }
}

resource "aws_iam_user_policy_attachment" "upload_access_policy_attachment" {
  user       = aws_iam_user.upload_access_user.name
  policy_arn = aws_iam_policy.s3_access_policy.arn
}
