
/* =========================================================
   DATABASE
========================================================= */

IF DB_ID('Radix_OS') IS NULL
BEGIN
    CREATE DATABASE Radix_OS;
END
GO

USE Radix_OS;
GO


/* =========================================================
   CLEAN RESET
========================================================= */

-- DROP VIEW IF EXISTS dbo.vAuthenticationEffectivePermissions;
-- DROP VIEW IF EXISTS dbo.vAuthenticationRoles;
-- DROP VIEW IF EXISTS dbo.vAuthenticationGroups;
-- DROP VIEW IF EXISTS dbo.vGroupHierarchy;
-- DROP VIEW IF EXISTS dbo.vAuthentications;
-- DROP VIEW IF EXISTS dbo.vEventLog;
-- DROP VIEW IF EXISTS dbo.vNotifyTray;

-- DROP TABLE IF EXISTS dbo.AuthenticationRoles;
-- DROP TABLE IF EXISTS dbo.AuthenticationGroups;
-- DROP TABLE IF EXISTS dbo.GroupRoles;
-- DROP TABLE IF EXISTS dbo.RolePermissions;
-- DROP TABLE IF EXISTS dbo.GroupClosure;

-- DROP TABLE IF EXISTS dbo.NotifyTray;
-- DROP TABLE IF EXISTS dbo.NotifyTrayObjects;
-- DROP TABLE IF EXISTS dbo.EventLog;
-- DROP TABLE IF EXISTS dbo.EventLevels;

-- DROP TABLE IF EXISTS dbo.Authentication;
-- DROP TABLE IF EXISTS dbo.[Group];
-- DROP TABLE IF EXISTS dbo.[Role];
-- DROP TABLE IF EXISTS dbo.Permission;
-- DROP TABLE IF EXISTS dbo.Plugins;
-- DROP TABLE IF EXISTS dbo.ObjectSource;
-- DROP TABLE IF EXISTS dbo.AuthenticationUAC;
-- DROP TABLE IF EXISTS dbo.Vault;
GO


/* =========================================================
   CORE TABLES
========================================================= */
CREATE TABLE dbo.Vault (
	ID int IDENTITY(1,1) NOT NULL,
	CustomerGUID uniqueidentifier NOT NULL,
	Feature nvarchar(128) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
	Payload nvarchar(MAX) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
	Signature nvarchar(MAX) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
	Active bit DEFAULT 1 NOT NULL,
	ExpiresAt datetime NULL,
	CreatedAt datetime DEFAULT getdate() NOT NULL,
	UpdatedAt datetime DEFAULT getdate() NULL,
	CONSTRAINT PK__Vault__3214EC275180843D PRIMARY KEY (ID)
);


CREATE TABLE dbo.ObjectSource (
    ID INT IDENTITY(1,1) PRIMARY KEY,
    Name VARCHAR(100) NOT NULL UNIQUE
);

CREATE TABLE dbo.AuthenticationUAC (
    ID INT PRIMARY KEY,
    AttributeName NVARCHAR(100),
    AttributeOriginal VARCHAR(255)
);

CREATE TABLE dbo.[Role] (
    ID INT IDENTITY(1,1) PRIMARY KEY,
    Name NVARCHAR(255) UNIQUE,
    Description NVARCHAR(MAX),
    RoleType VARCHAR(50)
);

CREATE TABLE dbo.Permission (
    ID INT IDENTITY(1,1) PRIMARY KEY,
    Scope VARCHAR(100),
    Resource VARCHAR(100),
    Action VARCHAR(100),
    CONSTRAINT UQ_Permission UNIQUE (Scope, Resource, Action)
);

CREATE TABLE dbo.Plugins (
    Name VARCHAR(50) PRIMARY KEY,
    Active BIT,
    Version VARCHAR(25)
);


/* =========================================================
   AUTHENTICATION
========================================================= */

CREATE TABLE dbo.Authentication (
    ObjectGUID UNIQUEIDENTIFIER PRIMARY KEY,

    sAMAccountName VARCHAR(255),
    mail VARCHAR(255),
    givenName VARCHAR(255),
    sn VARCHAR(255),

    employeeID VARCHAR(255),
    title VARCHAR(255),
    department VARCHAR(255),
    streetAddress VARCHAR(255),

    userAccountControl_ID INT,

    telephoneNumber VARCHAR(255),
    physicalDeliveryOfficeName VARCHAR(255),
    distinguishedName VARCHAR(MAX),

    password VARCHAR(MAX),
    refreshtoken VARCHAR(MAX),

    active BIT,
    online BIT,

    ObjectSource_ID INT,
    FOREIGN KEY (ObjectSource_ID) REFERENCES dbo.ObjectSource(ID)
);

CREATE TABLE dbo.[Group] (
    ObjectGUID UNIQUEIDENTIFIER PRIMARY KEY,
    Name VARCHAR(255),
    ObjectSource_ID INT,
    distinguishedName VARCHAR(MAX),
    FOREIGN KEY (ObjectSource_ID) REFERENCES dbo.ObjectSource(ID)
);


/* =========================================================
   GROUP CLOSURE
========================================================= */

CREATE TABLE dbo.GroupClosure (
    ParentGroup_ObjectGUID UNIQUEIDENTIFIER,
    ChildGroup_ObjectGUID UNIQUEIDENTIFIER,
    Depth INT,
    PRIMARY KEY (ParentGroup_ObjectGUID, ChildGroup_ObjectGUID)
);
GO

/* =========================================================
   RBAC
========================================================= */

CREATE TABLE dbo.AuthenticationRoles (
    Authentication_ObjectGUID UNIQUEIDENTIFIER,
    Role_ID INT,
    PRIMARY KEY (Authentication_ObjectGUID, Role_ID)
);
GO 

CREATE TABLE dbo.AuthenticationGroups (
    Authentication_ObjectGUID UNIQUEIDENTIFIER,
    Group_ObjectGUID UNIQUEIDENTIFIER,
    PRIMARY KEY (Authentication_ObjectGUID, Group_ObjectGUID)
);
GO

CREATE TABLE dbo.GroupRoles (
    Group_ObjectGUID UNIQUEIDENTIFIER,
    Role_ID INT,
    PRIMARY KEY (Group_ObjectGUID, Role_ID)
);
GO

CREATE TABLE dbo.RolePermissions (
    Role_ID INT,
    Permission_ID INT,
    PRIMARY KEY (Role_ID, Permission_ID)
);
GO

/* =========================================================
   EVENT SYSTEM
========================================================= */

CREATE TABLE dbo.EventLevels (
    ID INT PRIMARY KEY,
    LevelName VARCHAR(50),
    DisplayName VARCHAR(150),
    Priority INT
);

CREATE TABLE dbo.EventLog (
    ID INT IDENTITY(1,1) PRIMARY KEY,
    Message VARCHAR(MAX),
    Trace VARCHAR(MAX),
    Level_ID INT,
    PluginName VARCHAR(50),
    Date DATETIME2,
    ObjectGUID UNIQUEIDENTIFIER
);


/* =========================================================
   NOTIFY SYSTEM
========================================================= */

CREATE TABLE dbo.NotifyTrayObjects (
    ID INT IDENTITY(1,1) PRIMARY KEY,
    PluginName VARCHAR(50),
    Message VARCHAR(MAX),
    JSON VARCHAR(MAX),
    ActionRequired BIT DEFAULT 0,
    CreatedAt DATETIME2,
    ExpiresAt DATETIME2
);
GO

CREATE TABLE dbo.NotifyTray (
    ID INT IDENTITY(1,1) PRIMARY KEY,
    ObjectGUID UNIQUEIDENTIFIER,
    NotifyTrayObject_ID INT,
    SeenAt DATETIME2
);
GO

/* =========================================================
   SECURITY VIEWS
========================================================= */

CREATE VIEW dbo.vAuthenticationRoles AS
SELECT a.ObjectGUID, r.ID Role_ID, r.Name, 'DIRECT' Source
FROM dbo.Authentication a
JOIN dbo.AuthenticationRoles ar ON ar.Authentication_ObjectGUID = a.ObjectGUID
JOIN dbo.[Role] r ON r.ID = ar.Role_ID

UNION ALL

SELECT a.ObjectGUID, r.ID, r.Name, 'GROUP'
FROM dbo.Authentication a
JOIN dbo.AuthenticationGroups ag ON ag.Authentication_ObjectGUID = a.ObjectGUID
JOIN dbo.GroupRoles gr ON gr.Group_ObjectGUID = ag.Group_ObjectGUID
JOIN dbo.[Role] r ON r.ID = gr.Role_ID;
GO

CREATE VIEW dbo.vAuthenticationEffectivePermissions AS
SELECT DISTINCT
    a.ObjectGUID,
    p.Scope,
    p.Resource,
    p.Action,
    CONCAT(p.Scope,'.',p.Resource,'.',p.Action) PermissionKey
FROM dbo.Authentication a
JOIN dbo.vAuthenticationRoles r ON r.ObjectGUID = a.ObjectGUID
JOIN dbo.RolePermissions rp ON rp.Role_ID = r.Role_ID
JOIN dbo.Permission p ON p.ID = rp.Permission_ID;
GO

/* =========================================================
   FIXED vEventLog (SEQUELIZE MATCH + SYSTEM FIX)
========================================================= */

CREATE OR ALTER VIEW dbo.vEventLog
AS
SELECT
    e.ID,
    e.Message,
    e.Trace,
    e.Date,

    e.Level_ID,
    el.LevelName,
    el.DisplayName AS LevelDisplayName,
    el.Priority AS LevelPriority,

    e.PluginName,

    COALESCE(a.sn + ' ' + a.givenName, 'SYSTEM') AS ClearTextUser,

    a.sn AS Surname,
    a.givenName,

    e.ObjectGUID,

    a.sAMAccountName,
    a.mail,
    a.department,

    a.telephoneNumber AS Phone,
    a.physicalDeliveryOfficeName AS Office,
    a.streetAddress AS Adress,

    COALESCE(a.ObjectSource_ID, 1) AS ObjectSource_ID,
    os.Name AS ObjectSourceName

FROM dbo.EventLog e
LEFT JOIN dbo.Authentication a ON a.ObjectGUID = e.ObjectGUID
LEFT JOIN dbo.EventLevels el ON el.ID = e.Level_ID
LEFT JOIN dbo.ObjectSource os ON os.ID = COALESCE(a.ObjectSource_ID, 1);
GO


/* =========================================================
   AUTH VIEW
========================================================= */

CREATE VIEW dbo.vAuthentications AS
SELECT a.*, os.Name AS ObjectSource
FROM dbo.Authentication a
LEFT JOIN dbo.ObjectSource os ON os.ID = a.ObjectSource_ID;
GO

/* =========================================================
   GROUP VIEW
========================================================= */

CREATE VIEW dbo.vGroupHierarchy AS
SELECT * FROM dbo.GroupClosure;
GO

/* =========================================================
   NOTIFY VIEWS
========================================================= */
CREATE VIEW vNotifyTray AS
SELECT
    n.ID,
    n.ObjectGUID,
    n.SeenAt,

    a.sAMAccountName,
    a.givenName,
    a.sn,
    a.mail,
    a.active,
    a.online,
    
    nto.PluginName,
    nto.JSON,
    nto.ActionRequired,
    nto.CreatedAt,
    nto.Message

FROM NotifyTray n
LEFT JOIN Authentication a ON a.ObjectGUID = n.ObjectGUID
LEFT JOIN NotifyTrayObjects nto ON n.ID = n.NotifyTrayObject_ID

GO

/* =========================================================
   SEED DATA
========================================================= */

INSERT INTO dbo.ObjectSource VALUES ('LOCAL'),('AD');

INSERT INTO dbo.EventLevels VALUES
(-1,'test','Test',5),
(0,'success','Success',4),
(1,'log','Log',3),
(2,'warn','Warn',2),
(4,'error','Error',1),
(8,'throw_exception','Exception',0);

INSERT INTO dbo.Plugins VALUES ('SYSTEM',1,'1.0.0');

INSERT INTO dbo.[Role] (Name,Description,RoleType)
VALUES ('ADMIN','System Administrator','SYSTEM');

INSERT INTO dbo.Permission (Scope,Resource,Action)
VALUES ('SYSTEM','ALL','ALL');


INSERT INTO dbo.RolePermissions
SELECT r.ID, p.ID
FROM dbo.[Role] r
JOIN dbo.Permission p ON p.Scope='SYSTEM'
WHERE r.Name='ADMIN';


/* =========================================================
   ADMIN USER
========================================================= */

INSERT INTO dbo.Authentication (
    ObjectGUID,
    sAMAccountName,
    mail,
    givenName,
    sn,
    active,
    online,
    ObjectSource_ID
)
SELECT
    '00000000-0000-0000-0000-000000000001',
    'admin',
    'admin@local',
    'System',
    'Admin',
    1,
    0,
    ID
FROM dbo.ObjectSource
WHERE Name='LOCAL';


INSERT INTO dbo.AuthenticationRoles
SELECT
    '00000000-0000-0000-0000-000000000001',
    ID
FROM dbo.[Role]
WHERE Name='ADMIN';