-- Run this script against the Housing database before running the app.
-- It creates the login tables and login procedures.

IF OBJECT_ID(N'dbo.Operator_Account', N'U') IS NULL
BEGIN
    CREATE TABLE dbo.Operator_Account
    (
        [Operator] NVARCHAR(10) NOT NULL
            CONSTRAINT PK_Operator_Account PRIMARY KEY,
        [Password] NVARCHAR(50) NOT NULL,
        [CreatedAt] DATETIME2(0) NOT NULL
            CONSTRAINT DF_Operator_Account_CreatedAt DEFAULT (SYSDATETIME()),
        [UpdatedAt] DATETIME2(0) NULL
    );
END;
GO

IF COL_LENGTH(N'dbo.Operator_Account', N'IsActive') IS NOT NULL
BEGIN
    DECLARE @DefaultConstraintName SYSNAME;

    SELECT @DefaultConstraintName = dc.name
    FROM sys.default_constraints AS dc
    INNER JOIN sys.columns AS c
        ON c.default_object_id = dc.object_id
    WHERE dc.parent_object_id = OBJECT_ID(N'dbo.Operator_Account', N'U')
      AND c.name = N'IsActive';

    IF @DefaultConstraintName IS NOT NULL
    BEGIN
        EXEC(N'ALTER TABLE dbo.Operator_Account DROP CONSTRAINT [' + @DefaultConstraintName + N']');
    END;

    ALTER TABLE dbo.Operator_Account DROP COLUMN [IsActive];
END;
GO

IF OBJECT_ID(N'dbo.Operator_Process', N'U') IS NULL
BEGIN
    CREATE TABLE dbo.Operator_Process
    (
        [Operator] NVARCHAR(10) NOT NULL,
        [ProcessName] NVARCHAR(30) NOT NULL,
        [CreatedAt] DATETIME2(0) NOT NULL
            CONSTRAINT DF_Operator_Process_CreatedAt DEFAULT (SYSDATETIME()),
        CONSTRAINT PK_Operator_Process PRIMARY KEY ([Operator], [ProcessName]),
        CONSTRAINT FK_Operator_Process_Operator_Account FOREIGN KEY ([Operator])
            REFERENCES dbo.Operator_Account ([Operator])
            ON DELETE CASCADE
    );
END;
GO

IF EXISTS (SELECT 1 FROM dbo.Operator_Account WHERE [Operator] = N'su')
BEGIN
    UPDATE dbo.Operator_Account
    SET
        [Password] = N'su',
        [UpdatedAt] = SYSDATETIME()
    WHERE [Operator] = N'su';
END
ELSE
BEGIN
    INSERT INTO dbo.Operator_Account
    (
        [Operator],
        [Password]
    )
    VALUES
    (
        N'su',
        N'su'
    );
END;
GO

IF NOT EXISTS
(
    SELECT 1
    FROM dbo.Operator_Process
    WHERE [Operator] = N'su'
      AND [ProcessName] = N'Housing'
)
BEGIN
    INSERT INTO dbo.Operator_Process
    (
        [Operator],
        [ProcessName]
    )
    VALUES
    (
        N'su',
        N'Housing'
    );
END;
GO

CREATE OR ALTER PROCEDURE dbo.CheckOperator
    @Operator NVARCHAR(10),
    @Password NVARCHAR(50),
    @ProcessName NVARCHAR(30) = N'Housing'
AS
BEGIN
    SET NOCOUNT ON;

    SELECT CAST(
        CASE
            WHEN EXISTS
            (
                SELECT 1
                FROM dbo.Operator_Account AS account
                INNER JOIN dbo.Operator_Process AS process
                    ON process.[Operator] = account.[Operator]
                WHERE account.[Operator] = @Operator
                  AND account.[Password] = @Password
                  AND process.[ProcessName] = @ProcessName
            )
            THEN 1
            ELSE 0
        END AS BIT) AS IsValid;
END;
GO

CREATE OR ALTER PROCEDURE dbo.SaveOperator
    @Operator NVARCHAR(10),
    @Password NVARCHAR(50),
    @ProcessName NVARCHAR(30) = N'Housing'
AS
BEGIN
    SET NOCOUNT ON;
    SET XACT_ABORT ON;

    BEGIN TRANSACTION;

    UPDATE dbo.Operator_Account
    SET
        [Password] = @Password,
        [UpdatedAt] = SYSDATETIME()
    WHERE [Operator] = @Operator;

    IF @@ROWCOUNT = 0
    BEGIN
        INSERT INTO dbo.Operator_Account
        (
            [Operator],
            [Password]
        )
        VALUES
        (
            @Operator,
            @Password
        );
    END;

    IF NOT EXISTS
    (
        SELECT 1
        FROM dbo.Operator_Process
        WHERE [Operator] = @Operator
          AND [ProcessName] = @ProcessName
    )
    BEGIN
        INSERT INTO dbo.Operator_Process
        (
            [Operator],
            [ProcessName]
        )
        VALUES
        (
            @Operator,
            @ProcessName
        );
    END;

    COMMIT TRANSACTION;
END;
GO
