data "archive_file" "starter_o11y_stub" {
  count = local.starter_o11y_stub_enabled ? 1 : 0

  type        = "zip"
  source_file = "${path.module}/scripts/o11y_stub_lambda.py"
  output_path = "${path.module}/.terraform/cp9-starter-o11y-stub.zip"
}

resource "random_password" "starter_o11y_token" {
  count = local.starter_o11y_stub_enabled ? 1 : 0

  length  = 32
  special = false
}

resource "aws_dynamodb_table" "starter_o11y_evidence" {
  count = local.starter_o11y_stub_enabled ? 1 : 0

  name         = local.starter_o11y_stub_evidence_table_name
  billing_mode = "PAY_PER_REQUEST"
  hash_key     = "pk"
  range_key    = "sk"

  attribute {
    name = "pk"
    type = "S"
  }

  attribute {
    name = "sk"
    type = "S"
  }

  tags = merge(local.common_tags, {
    Name = local.starter_o11y_stub_evidence_table_name
  })
}

data "aws_iam_policy_document" "starter_o11y_lambda_assume" {
  count = local.starter_o11y_stub_enabled ? 1 : 0

  statement {
    effect  = "Allow"
    actions = ["sts:AssumeRole"]

    principals {
      type        = "Service"
      identifiers = ["lambda.amazonaws.com"]
    }
  }
}

resource "aws_iam_role" "starter_o11y_lambda" {
  count = local.starter_o11y_stub_enabled ? 1 : 0

  name                 = local.starter_o11y_stub_role_name
  assume_role_policy   = data.aws_iam_policy_document.starter_o11y_lambda_assume[0].json
  permissions_boundary = local.developer_boundary_policy_arn

  tags = merge(local.common_tags, {
    Name = local.starter_o11y_stub_role_name
  })
}

data "aws_iam_policy_document" "starter_o11y_lambda" {
  count = local.starter_o11y_stub_enabled ? 1 : 0

  statement {
    effect = "Allow"
    actions = [
      "dynamodb:PutItem",
      "dynamodb:UpdateItem",
    ]
    resources = [aws_dynamodb_table.starter_o11y_evidence[0].arn]
  }

  statement {
    effect = "Allow"
    actions = [
      "logs:CreateLogGroup",
      "logs:CreateLogStream",
      "logs:PutLogEvents",
    ]
    resources = [
      "arn:aws:logs:${local.target_region}:${local.target_account}:log-group:/aws/lambda/${local.starter_o11y_stub_function_name}",
      "arn:aws:logs:${local.target_region}:${local.target_account}:log-group:/aws/lambda/${local.starter_o11y_stub_function_name}:*",
    ]
  }

  statement {
    sid       = "DecryptLambdaEnvironment"
    effect    = "Allow"
    actions   = ["kms:Decrypt"]
    resources = ["arn:aws:kms:${local.target_region}:${local.target_account}:key/*"]

    condition {
      test     = "StringEquals"
      variable = "kms:ViaService"
      values   = ["lambda.${local.target_region}.amazonaws.com"]
    }
  }
}

resource "aws_iam_role_policy" "starter_o11y_lambda" {
  count = local.starter_o11y_stub_enabled ? 1 : 0

  name   = "cp9-starter-o11y"
  role   = aws_iam_role.starter_o11y_lambda[0].id
  policy = data.aws_iam_policy_document.starter_o11y_lambda[0].json
}

resource "aws_lambda_function" "starter_o11y_stub" {
  count = local.starter_o11y_stub_enabled ? 1 : 0

  function_name    = local.starter_o11y_stub_function_name
  role             = aws_iam_role.starter_o11y_lambda[0].arn
  handler          = "o11y_stub_lambda.handler"
  runtime          = "python3.12"
  filename         = data.archive_file.starter_o11y_stub[0].output_path
  source_code_hash = data.archive_file.starter_o11y_stub[0].output_base64sha256
  timeout          = 10

  environment {
    variables = {
      CP9_O11Y_EVIDENCE_TABLE = aws_dynamodb_table.starter_o11y_evidence[0].name
      CP9_O11Y_SCRIPT         = local.starter_o11y_stub_script
      CP9_O11Y_TOKEN          = random_password.starter_o11y_token[0].result
    }
  }

  tags = merge(local.common_tags, {
    Name = local.starter_o11y_stub_function_name
  })

  depends_on = [aws_iam_role_policy.starter_o11y_lambda]
}

resource "aws_lambda_function_url" "starter_o11y_stub" {
  count = local.starter_o11y_stub_enabled ? 1 : 0

  function_name      = aws_lambda_function.starter_o11y_stub[0].function_name
  authorization_type = "NONE"
}

resource "aws_lambda_permission" "starter_o11y_stub_url" {
  count = local.starter_o11y_stub_enabled ? 1 : 0

  statement_id             = "AllowPublicFunctionUrlInvoke"
  action                   = "lambda:InvokeFunction"
  function_name            = aws_lambda_function.starter_o11y_stub[0].function_name
  principal                = "*"
  invoked_via_function_url = true
}
