provider "aws" {
  region = var.region
}

terraform {
  backend "s3" {
    bucket  = "orcd-terraform-state"
    key     = "prod/neighbouring-rights/bucket/terraform.tfstate"
    region  = "us-east-1"
    encrypt = "true"
  }
}


module "s3_bucket" {
  source              = "git@github.com:theorchard/terraform-s3.git//modules/s3_bucket?ref=3.12.1"
  env                 = var.environment
  bucket_name         = "neighbouring-rights"
  acceleration_status = "Enabled"
  application_family  = var.application_family
  apply_server_side_encryption_by_default = {
    sse_algorithm = "AES256"
  }

  # CORS Rules
  bucket_cors_rule = [
    {
      allowed_headers = ["*"]
      allowed_methods = ["PUT", "POST"]
      allowed_origins = [
        "https://content.theorchard.com",
        "https://distribution.theorchard.com",
      ]
      expose_headers  = ["ETag"]
      max_age_seconds = 3000
    }
  ]

  lifecycle_rules_options_noncurrent_version_expiration = [
    {
      prefix  = "delivery"
      enabled = true
      days    = 15
    },
    {
      prefix  = "ingestion"
      enabled = true
      days    = 15
    },
     {
      enabled = true
      prefix  = "ownership/ingestion"
      days    = 15
    },
    {
      enabled = true
      prefix  = "ownership/delivery"
      days    = 15
    }
  ]

  lifecycle_rules_options_current_version_expiration = [
    # Delete everything in ingestion/processing/ after 31 days
    {
      enabled = true
      prefix  = "ingestion/processing/"
      days    = 31
    },
    # 1 month policy for the uploaded files
    {
      enabled = true
      prefix  = "ingestion/uploads/"
      days    = 31
    },
    # 1 month policy for the generated report files
    {
      enabled = true
      prefix  = "ingestion/reports/"
      days    = 31
    },
     {
      enabled = true
      prefix  = "ownership/ingestion/processing"
      days    = 31
    },
    {
      enabled = true
      prefix  = "ownership/ingestion/uploads"
      days    = 31
    }
  ]

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

  apply_replication_configuration = [{
    priority                          = 0
    prefix                            = "contributions/"
    destination_bucket                = var.replication_destination
    delete_marker_replication_enabled = false
    storage_class                     = "STANDARD"
    enabled                           = true
    },
    {
      priority                          = 1
      prefix                            = "cmo-templates/"
      destination_bucket                = var.replication_destination
      delete_marker_replication_enabled = false
      storage_class                     = "STANDARD"
      enabled                           = true
    },
    {
      priority                          = 2
      prefix                            = "delivery/orders/"
      destination_bucket                = var.replication_destination
      delete_marker_replication_enabled = false
      storage_class                     = "STANDARD"
      enabled                           = true
  },
  {
      priority                          = 3
      prefix                            = "ownership/delivery/orders/"
      destination_bucket                = var.replication_destination
      delete_marker_replication_enabled = false
      storage_class                     = "STANDARD"
      enabled                           = true
  }]
}

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

    actions = [
      "s3:PutObject",
    ]

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

resource "aws_iam_policy" "input_bucket_putonly_policy" {
  name        = "S3-${module.s3_bucket.s3_bucket_name_output}-WO"
  description = "Write access to neighbouring rights input bucket"
  policy      = data.aws_iam_policy_document.input_bucket_putonly_policy.json
}

data "aws_iam_policy_document" "input_bucket_readonly_policy" {
  statement {
    actions = [
      "s3:GetObject",
    ]

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

  statement {
    actions = [
      "s3:ListBucket",
      "s3:GetBucketLocation"
    ]

    resources = [
      module.s3_bucket.s3_bucket_arn_output
    ]
  }
}

resource "aws_iam_policy" "input_bucket_readonly_policy" {
  name        = "S3-${module.s3_bucket.s3_bucket_name_output}-RO"
  description = "Read access to neighbouring rights input bucket"
  policy      = data.aws_iam_policy_document.input_bucket_readonly_policy.json
}

data "aws_iam_policy_document" "ingestion_bucket_rw_policy" {
  statement {
    actions = [
      "s3:GetObject",
    ]

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

  statement {
    actions = [
      "s3:PutObject",
      "s3:DeleteObject",
    ]

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

  statement {
    actions = [
      "s3:ListBucket",
      "s3:GetBucketLocation"
    ]

    resources = [
      module.s3_bucket.s3_bucket_arn_output
    ]
  }
}

resource "aws_iam_policy" "ingestion_bucket_rw_policy" {
  name        = "S3-${module.s3_bucket.s3_bucket_name_output}-ingestion-RW"
  description = "Read, Write, Delete access to NR ingestion bucket"
  policy      = data.aws_iam_policy_document.ingestion_bucket_rw_policy.json
}

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

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

    resources = [
      module.s3_bucket.s3_bucket_arn_output
    ]
  }

  statement {
    effect = "Allow"

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

    resources = [
      "${module.s3_bucket.s3_bucket_arn_output}/delivery/*",
    ]
  }
}

resource "aws_iam_policy" "delivery_bucket_rw_policy" {
  name        = "S3-${module.s3_bucket.s3_bucket_name_output}-delivery-RW"
  description = "Write access to delivery folder in neighbouring rights bucket"
  policy      = data.aws_iam_policy_document.delivery_bucket_rw_policy_document.json
}


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

    actions = [
      "s3:GetObject",
      "s3:GetObjectVersion",
    ]

    resources = [
      "${module.s3_bucket.s3_bucket_arn_output}/contributions/*",
    ]
  }
  statement {
    effect = "Allow"

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

    resources = [
      "${module.s3_bucket.s3_bucket_arn_output}",
    ]
  }
}

resource "aws_iam_policy" "contributions_bucket_read_policy" {
  name        = "S3-${module.s3_bucket.s3_bucket_name_output}-contributions-R"
  description = "Read access to contributions folder in neighbouring rights bucket"
  policy      = data.aws_iam_policy_document.contributions_bucket_read_policy_document.json
}

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

    actions = [
      "s3:GetObject",
      "s3:GetObjectVersion",
      "s3:DeleteObject",
      "s3:DeleteObjectVersion"
    ]

    resources = [
      "${module.s3_bucket.s3_bucket_arn_output}/contributions/*"
    ]
  }
  statement {
    effect = "Allow"

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

    resources = [
      module.s3_bucket.s3_bucket_arn_output
    ]
  }
}

resource "aws_iam_policy" "contributions_bucket_rw_policy_document" {
  name        = "S3-${module.s3_bucket.s3_bucket_name_output}-contributions-RW"
  description = "Read, Delete access to contributions folder in neighbouring rights bucket"
  policy      = data.aws_iam_policy_document.contributions_bucket_rw_policy_document.json
}

# Assume role policy used by Jenkins pipeline agent role
data "aws_iam_policy_document" "jenkins_assume_role_policy" {
  statement {
    actions = ["sts:AssumeRole"]

    principals {
      type = "AWS"

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

resource "aws_iam_role" "contributions_bucket_rw_role" {
  name                 = "S3-${module.s3_bucket.s3_bucket_name_output}-contributions-RW-role"
  assume_role_policy   = data.aws_iam_policy_document.jenkins_assume_role_policy.json
  max_session_duration = 7200
}

resource "aws_iam_role_policy_attachment" "contributions_bucket_rw_role_policy_attachment" {
  role       = aws_iam_role.contributions_bucket_rw_role.name
  policy_arn = aws_iam_policy.contributions_bucket_rw_policy_document.arn
}

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

    actions = [
      "s3:GetObject",
    ]

    resources = [
      "${module.s3_bucket.s3_bucket_arn_output}/cmo-templates/*",
    ]
  }
}

resource "aws_iam_policy" "cmo_templates_bucket_read_policy" {
  name        = "S3-${module.s3_bucket.s3_bucket_name_output}-cmo-templates-R"
  description = "Read access to cmo-templates folder in neighbouring rights bucket"
  policy      = data.aws_iam_policy_document.cmo_templates_bucket_read_policy_document.json
}

data "aws_iam_role" "fargate_task_iam_role_name" {
  name = "${var.environment}-graphql-neighbouring-rights-task-role"
}

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

    actions = [
      "sts:AssumeRole",
    ]

    principals {
      type        = "AWS"
      identifiers = [data.aws_iam_role.fargate_task_iam_role_name.arn]
    }
  }
}

resource "aws_iam_role" "neighbouring_rights_browser_upload_role" {
  name                 = "${var.environment}-neighbouring-rights-browser-upload-role"
  max_session_duration = 3600
  assume_role_policy   = data.aws_iam_policy_document.assume_role_policy.json
}

resource "aws_iam_role_policy_attachment" "neighbouring_rights_browser_upload_policy_attachment" {
  role       = aws_iam_role.neighbouring_rights_browser_upload_role.id
  policy_arn = aws_iam_policy.input_bucket_putonly_policy.arn
}

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

    actions = [
      "sts:AssumeRole",
    ]

    resources = [
      aws_iam_role.neighbouring_rights_browser_upload_role.arn
    ]
  }
}


resource "aws_iam_policy" "neighbouring_rights_browser_upload_assume_role_policy" {
  name        = "${var.environment}-neighbouring-rights-browser-upload-assume-role-policy"
  description = "Assume browser upload role used by the neighbouring rights fargate role."
  policy      = data.aws_iam_policy_document.neighbouring_rights_browser_upload_assume_role_policy_document.json
}

resource "aws_iam_role_policy_attachment" "neighbouring_rights_browser_upload_policy_attachment_to_fargate" {
  role       = data.aws_iam_role.fargate_task_iam_role_name.name
  policy_arn = aws_iam_policy.neighbouring_rights_browser_upload_assume_role_policy.arn
}


data "aws_iam_policy_document" "neighbouring_rights_ownership_ingestion_processing_errors_ro" {
  statement {
    actions = [
      "s3:GetObject*",
    ]

    resources = [
      "${module.s3_bucket.s3_bucket_arn_output}/ownership/ingestion/processing/orchard/errors/*",
    ]
  }

  statement {
    actions = [
      "s3:GetBucketLocation",
      "s3:ListBucket"
    ]

    resources = [
      module.s3_bucket.s3_bucket_arn_output
    ]
  }
}

resource "aws_iam_policy" "neighbouring_rights_ownership_ingestion_processing_errors_ro" {
  name   = "S3-${module.s3_bucket.s3_bucket_name_output}-ownership-ingestion-processing-errors-ro"
  policy = data.aws_iam_policy_document.neighbouring_rights_ownership_ingestion_processing_errors_ro.json
}

resource "aws_iam_group" "neighbouring_rights_ownership_ingestion_processing_errors_ro_group" {
  name = "${module.s3_bucket.s3_bucket_name_output}-ownership-ingestion-processing-errors-ro-group"
}

resource "aws_iam_group_membership" "neighbouring_rights_ownership_ingestion_processing_errors_ro_group" {
  name = "${module.s3_bucket.s3_bucket_name_output}-ownership-ingestion-processing-errors-ro-group"

  users = [
    "jeden",
    "sbirkwood",
    "mhermalyn",
    "llowe",
    "aroncero",
    "cwijesinghe-gibbs",
    "clang"
  ]

  group = aws_iam_group.neighbouring_rights_ownership_ingestion_processing_errors_ro_group.name
}

resource "aws_iam_group_policy_attachment" "neighbouring_rights_ownership_ingestion_processing_errors_ro_group_policy_attachment" {
  group      = aws_iam_group.neighbouring_rights_ownership_ingestion_processing_errors_ro_group.name
  policy_arn = aws_iam_policy.neighbouring_rights_ownership_ingestion_processing_errors_ro.arn
}
