import { type CommonQueryMethods, sql } from '@silverhand/slonik';

import type { AlterationScript } from '../lib/types/alteration.js';

const getId = (value: string) => sql.identifier([value]);

const getDatabaseName = async (pool: CommonQueryMethods) => {
  const { currentDatabase } = await pool.one<{ currentDatabase: string }>(sql`
    select current_database();
  `);

  return currentDatabase.replaceAll('-', '_');
};

const alteration: AlterationScript = {
  up: async (pool) => {
    const database = await getDatabaseName(pool);
    const baseRoleId = getId(`logto_tenant_${database}`);

    await pool.query(sql`
      create table sso_connectors (
        tenant_id varchar(21) not null
          references tenants (id) on update cascade on delete cascade,
        id varchar(128) not null,
        provider_name varchar(128) not null,
        connector_name varchar(128) not null,
        config jsonb not null default '{}'::jsonb,
        domains jsonb not null default '[]'::jsonb,
        branding jsonb not null default '{}'::jsonb,
        sync_profile boolean not null default FALSE,
        sso_only boolean not null default FALSE,
        created_at timestamptz not null default(now()),
        primary key (id)
      );

      create index sso_connectors__id
        on sso_connectors (tenant_id, id);

      create index sso_connectors__id__provider_name
        on sso_connectors (tenant_id, id, provider_name);

      create trigger set_tenant_id before insert on sso_connectors
        for each row execute procedure set_tenant_id();

      alter table sso_connectors enable row level security;

      create policy sso_connectors_tenant_id on sso_connectors
        as restrictive
        using (tenant_id = (select id from tenants where db_user = current_user));

      create policy sso_connectors_modification on sso_connectors
        using (true);

      grant select, insert, update, delete on sso_connectors to ${baseRoleId};
    `);
  },
  down: async (pool) => {
    await pool.query(sql`
      drop policy sso_connectors_modification on sso_connectors;
      drop policy sso_connectors_tenant_id on sso_connectors;
      drop table sso_connectors;
    `);
  },
};

export default alteration;