
/* =========================================================
   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';
GO

/* =========================================================
   EXTENDED RBAC VIEWS
========================================================= */

-- ========================================================
-- 1. USER GROUPS (DIRECT + INHERITED)
-- ========================================================
CREATE OR ALTER VIEW dbo.vAuthenticationGroupsExpanded AS
SELECT 
    ag.Authentication_ObjectGUID,
    g.ObjectGUID AS GroupGUID,
    g.Name AS GroupName,
    'DIRECT' AS Source
FROM dbo.AuthenticationGroups ag
JOIN dbo.[Group] g 
    ON g.ObjectGUID = ag.Group_ObjectGUID

UNION ALL

SELECT 
    ag.Authentication_ObjectGUID,
    gc.ParentGroup_ObjectGUID,
    g.Name,
    'INHERITED'
FROM dbo.AuthenticationGroups ag
JOIN dbo.GroupClosure gc 
    ON gc.ChildGroup_ObjectGUID = ag.Group_ObjectGUID
JOIN dbo.[Group] g 
    ON g.ObjectGUID = gc.ParentGroup_ObjectGUID;
GO


-- ========================================================
-- 2. ROLES (DIRECT + GROUP + HIERARCHY)
-- ========================================================
CREATE OR ALTER VIEW dbo.vAuthenticationRolesExpanded AS
SELECT 
    ar.Authentication_ObjectGUID,
    ar.Role_ID,
    r.Name AS RoleName,
    'DIRECT' AS Source
FROM dbo.AuthenticationRoles ar
JOIN dbo.[Role] r 
    ON r.ID = ar.Role_ID

UNION ALL

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

UNION ALL

SELECT 
    ag.Authentication_ObjectGUID,
    gr.Role_ID,
    r.Name,
    'GROUP_INHERITED'
FROM dbo.AuthenticationGroups ag
JOIN dbo.GroupClosure gc 
    ON gc.ChildGroup_ObjectGUID = ag.Group_ObjectGUID
JOIN dbo.GroupRoles gr 
    ON gr.Group_ObjectGUID = gc.ParentGroup_ObjectGUID
JOIN dbo.[Role] r 
    ON r.ID = gr.Role_ID;
GO


-- ========================================================
-- 3. EFFECTIVE ROLES (DEDUPLICATED)
-- ========================================================
CREATE OR ALTER VIEW dbo.vAuthenticationEffectiveRoles AS
SELECT DISTINCT
    Authentication_ObjectGUID,
    Role_ID,
    RoleName
FROM dbo.vAuthenticationRolesExpanded;
GO


-- ========================================================
-- 4. PERMISSIONS (DETAILED WITH ROLE SOURCE)
-- ========================================================
CREATE OR ALTER VIEW dbo.vAuthenticationPermissionsDetailed AS
SELECT 
    r.Authentication_ObjectGUID,
    r.Role_ID,
    r.RoleName,
    p.Scope,
    p.Resource,
    p.Action,
    CONCAT(p.Scope,'.',p.Resource,'.',p.Action) AS PermissionKey
FROM dbo.vAuthenticationRolesExpanded r
JOIN dbo.RolePermissions rp 
    ON rp.Role_ID = r.Role_ID
JOIN dbo.Permission p 
    ON p.ID = rp.Permission_ID;
GO


-- ========================================================
-- 5. PERMISSION MATRIX (FAST LOOKUP)
-- ========================================================
CREATE OR ALTER VIEW dbo.vPermissionMatrix AS
SELECT DISTINCT
    Authentication_ObjectGUID,
    CONCAT(Scope,'.',Resource,'.',Action) AS PermissionKey
FROM dbo.vAuthenticationPermissionsDetailed;
GO


-- ========================================================
-- 6. GROUP ROLES OVERVIEW
-- ========================================================
CREATE OR ALTER VIEW dbo.vGroupRolesDetailed AS
SELECT 
    g.ObjectGUID,
    g.Name AS GroupName,
    r.ID AS Role_ID,
    r.Name AS RoleName
FROM dbo.GroupRoles gr
JOIN dbo.[Group] g 
    ON g.ObjectGUID = gr.Group_ObjectGUID
JOIN dbo.[Role] r 
    ON r.ID = gr.Role_ID;
GO


-- ========================================================
-- 7. GROUP HIERARCHY (READABLE)
-- ========================================================
CREATE OR ALTER VIEW dbo.vGroupHierarchyReadable AS
SELECT 
    parent.ObjectGUID AS ParentGroupGUID,
    parent.Name AS ParentGroupName,
    child.ObjectGUID AS ChildGroupGUID,
    child.Name AS ChildGroupName,
    gc.Depth
FROM dbo.GroupClosure gc
JOIN dbo.[Group] parent 
    ON parent.ObjectGUID = gc.ParentGroup_ObjectGUID
JOIN dbo.[Group] child 
    ON child.ObjectGUID = gc.ChildGroup_ObjectGUID;
GO


-- ========================================================
-- 8. USER OVERVIEW (ADMIN DASHBOARD)
-- ========================================================
CREATE OR ALTER VIEW dbo.vAuthenticationOverview AS
SELECT        a.ObjectGUID, a.sAMAccountName, a.mail, a.givenName, a.sn, a.active, a.online, COUNT(DISTINCT r.Role_ID) AS RoleCount, COUNT(DISTINCT g.GroupGUID) AS GroupCount, a.title, a.department, a.streetAddress, 
                         a.telephoneNumber, a.physicalDeliveryOfficeName, a.distinguishedName, dbo.ObjectSource.Name AS ObjectSourceName
FROM            dbo.Authentication AS a LEFT OUTER JOIN
                         dbo.ObjectSource ON a.ObjectSource_ID = dbo.ObjectSource.ID LEFT OUTER JOIN
                         dbo.vAuthenticationRolesExpanded AS r ON r.Authentication_ObjectGUID = a.ObjectGUID LEFT OUTER JOIN
                         dbo.vAuthenticationGroupsExpanded AS g ON g.Authentication_ObjectGUID = a.ObjectGUID
GROUP BY a.ObjectGUID, a.sAMAccountName, a.mail, a.givenName, a.sn, a.active, a.online, a.title, a.department, a.streetAddress, a.telephoneNumber, a.physicalDeliveryOfficeName, a.distinguishedName, dbo.ObjectSource.Name
GO


-- ========================================================
-- 8.1. GROUP OVERVIEW (ADMIN DASHBOARD)
-- ========================================================
CREATE OR ALTER VIEW dbo.vGroupOverview AS
SELECT        dbo.[Group].ObjectGUID, dbo.[Group].Name, COUNT(DISTINCT ag.Authentication_ObjectGUID) AS UserCount, COUNT(DISTINCT gr.Role_ID) AS RoleCount, dbo.ObjectSource.Name AS ObjectSourceName, 
                         dbo.[Group].distinguishedName
FROM            dbo.ObjectSource RIGHT OUTER JOIN
                         dbo.[Group] ON dbo.ObjectSource.ID = dbo.[Group].ObjectSource_ID LEFT OUTER JOIN
                         dbo.AuthenticationGroups AS ag ON dbo.[Group].ObjectGUID = ag.Group_ObjectGUID LEFT OUTER JOIN
                         dbo.GroupRoles AS gr ON dbo.[Group].ObjectGUID = gr.Group_ObjectGUID
GROUP BY dbo.[Group].ObjectGUID, dbo.[Group].Name, dbo.ObjectSource.Name, dbo.[Group].distinguishedName


-- ========================================================
-- 9. BONUS: PERMISSION TRACE (WHY DOES USER HAVE THIS?)
-- ========================================================
CREATE OR ALTER VIEW dbo.vPermissionTrace AS
SELECT 
    apd.Authentication_ObjectGUID,
    apd.RoleName,
    apd.Scope,
    apd.Resource,
    apd.Action,
    apd.PermissionKey
FROM dbo.vAuthenticationPermissionsDetailed apd;
GO