using Microsoft.EntityFrameworkCore.Migrations;

#nullable disable

namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations;

/// <summary>
///     Creates the two DB roles per <c>config-db-schema.md §"Authorization Model"</c> and grants
///     EXECUTE on the appropriate stored procedures. Deliberately grants no direct table DML — all
///     writes funnel through the procs, which authenticate via <c>SUSER_SNAME()</c>.
///     Principals (SQL logins, gMSA users, cert-mapped users) are provisioned by the DBA outside
///     this migration and then added to one of the two roles.
/// </summary>
public partial class AuthorizationGrants : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.Sql(@"
IF DATABASE_PRINCIPAL_ID('OtOpcUaNode') IS NULL
    CREATE ROLE OtOpcUaNode;
IF DATABASE_PRINCIPAL_ID('OtOpcUaAdmin') IS NULL
    CREATE ROLE OtOpcUaAdmin;
");

        migrationBuilder.Sql(@"
GRANT EXECUTE ON OBJECT::dbo.sp_GetCurrentGenerationForCluster TO OtOpcUaNode;
GRANT EXECUTE ON OBJECT::dbo.sp_GetGenerationContent            TO OtOpcUaNode;
GRANT EXECUTE ON OBJECT::dbo.sp_RegisterNodeGenerationApplied   TO OtOpcUaNode;

GRANT EXECUTE ON OBJECT::dbo.sp_GetCurrentGenerationForCluster TO OtOpcUaAdmin;
GRANT EXECUTE ON OBJECT::dbo.sp_GetGenerationContent            TO OtOpcUaAdmin;
GRANT EXECUTE ON OBJECT::dbo.sp_ValidateDraft                   TO OtOpcUaAdmin;
GRANT EXECUTE ON OBJECT::dbo.sp_PublishGeneration               TO OtOpcUaAdmin;
GRANT EXECUTE ON OBJECT::dbo.sp_RollbackToGeneration            TO OtOpcUaAdmin;
GRANT EXECUTE ON OBJECT::dbo.sp_ComputeGenerationDiff           TO OtOpcUaAdmin;
GRANT EXECUTE ON OBJECT::dbo.sp_ReleaseExternalIdReservation    TO OtOpcUaAdmin;

DENY UPDATE, DELETE, INSERT ON SCHEMA::dbo TO OtOpcUaNode;
DENY UPDATE, DELETE, INSERT ON SCHEMA::dbo TO OtOpcUaAdmin;
DENY SELECT ON SCHEMA::dbo TO OtOpcUaNode;
-- Admins may SELECT for reporting views in the future — grant views explicitly, not the schema.
DENY SELECT ON SCHEMA::dbo TO OtOpcUaAdmin;
");
    }

    protected override void Down(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.Sql(@"
IF DATABASE_PRINCIPAL_ID('OtOpcUaNode') IS NOT NULL
    DROP ROLE OtOpcUaNode;
IF DATABASE_PRINCIPAL_ID('OtOpcUaAdmin') IS NOT NULL
    DROP ROLE OtOpcUaAdmin;
");
    }
}
