'use strict';

const PUBLIC_CONTEXT_TABLES = ['users', 'tenants', 'organizations'];

module.exports = {
  async up(queryInterface) {
    const transaction = await queryInterface.sequelize.transaction();

    try {
      await queryInterface.sequelize.query(
        'DROP POLICY IF EXISTS "organizations_self_or_global" ON "organizations"',
        { transaction },
      );

      for (const tableName of PUBLIC_CONTEXT_TABLES) {
        await queryInterface.sequelize.query(
          `DROP POLICY IF EXISTS "${tableName}_organization_isolation" ON "${tableName}"`,
          { transaction },
        );
        await queryInterface.sequelize.query(
          `ALTER TABLE "${tableName}" NO FORCE ROW LEVEL SECURITY`,
          { transaction },
        );
        await queryInterface.sequelize.query(
          `ALTER TABLE "${tableName}" DISABLE ROW LEVEL SECURITY`,
          { transaction },
        );
      }

      await transaction.commit();
    } catch (error) {
      await transaction.rollback();
      throw error;
    }
  },

  async down(queryInterface) {
    const transaction = await queryInterface.sequelize.transaction();

    try {
      await queryInterface.sequelize.query(
        'ALTER TABLE "organizations" ENABLE ROW LEVEL SECURITY',
        { transaction },
      );
      await queryInterface.sequelize.query(
        'ALTER TABLE "organizations" FORCE ROW LEVEL SECURITY',
        { transaction },
      );
      await queryInterface.sequelize.query(
        `
          CREATE POLICY "organizations_self_or_global"
          ON "organizations"
          FOR ALL
          USING (
            COALESCE(current_setting('app.global_access', true), 'false') = 'true'
            OR "id" = NULLIF(current_setting('app.current_org', true), '')::uuid
          )
          WITH CHECK (
            COALESCE(current_setting('app.global_access', true), 'false') = 'true'
            OR "id" = NULLIF(current_setting('app.current_org', true), '')::uuid
          )
        `,
        { transaction },
      );

      for (const tableName of ['users', 'tenants']) {
        await queryInterface.sequelize.query(
          `ALTER TABLE "${tableName}" ENABLE ROW LEVEL SECURITY`,
          { transaction },
        );
        await queryInterface.sequelize.query(
          `ALTER TABLE "${tableName}" FORCE ROW LEVEL SECURITY`,
          { transaction },
        );
        await queryInterface.sequelize.query(
          `
            CREATE POLICY "${tableName}_organization_isolation"
            ON "${tableName}"
            FOR ALL
            USING (
              COALESCE(current_setting('app.global_access', true), 'false') = 'true'
              OR "organizationsId" = NULLIF(current_setting('app.current_org', true), '')::uuid
            )
            WITH CHECK (
              COALESCE(current_setting('app.global_access', true), 'false') = 'true'
              OR "organizationsId" = NULLIF(current_setting('app.current_org', true), '')::uuid
            )
          `,
          { transaction },
        );
      }

      await transaction.commit();
    } catch (error) {
      await transaction.rollback();
      throw error;
    }
  },
};
