resource "postgresql_role" "datadog" {
  name  = "datadog"
  login = true

  roles = concat(["pg_monitor"], var.datadog_roles)
}

resource "postgresql_extension" "pg_stat_statements" {
  for_each = toset(var.databases)
  name     = "pg_stat_statements"
  database = each.value
}

resource "postgresql_schema" "this" {
  for_each      = toset(var.databases)
  name          = "datadog"
  database      = each.value
  owner         = var.owner
  if_not_exists = true
  drop_cascade  = false
}

resource "postgresql_grant" "public_schema_grant" {
  for_each    = toset(var.databases)
  database    = each.value
  role        = postgresql_role.datadog.name
  schema      = "public"
  object_type = "schema"
  privileges  = ["USAGE"]
}

resource "postgresql_grant" "datadog_schema_grant" {
  for_each    = toset(var.databases)
  database    = each.value
  role        = postgresql_role.datadog.name
  schema      = "datadog"
  object_type = "schema"
  privileges  = ["USAGE"]
}

# Something is missing:
# RETURNS NULL ON NULL INPUT
# SECURITY DEFINER
resource "postgresql_function" "explain" {
  for_each = toset(var.databases)
  database = each.value
  schema   = postgresql_schema.this[each.value].name
  name = "explain_statement"
  arg {
      mode = "IN"
      name = "l_query"
      type = "text"
  }
  arg {
      name = "explain"
      type = "json"
      mode = "OUT"
  }
  returns = "SETOF json"
  language = "plpgsql"

  body = <<-EOF

    DECLARE
    curs REFCURSOR;
    plan JSON;

    BEGIN
       OPEN curs FOR EXECUTE pg_catalog.concat('EXPLAIN (FORMAT JSON) ', l_query);
       FETCH curs INTO plan;
       CLOSE curs;
       RETURN QUERY SELECT plan;
    END;
  EOF
}
