// Package db defines the database schema.
package database

// CurrentSchemaVersion returns the current schema version (for migrations)
func CurrentSchemaVersion() int {
	return 1
}

// CreateTableStatements returns a list of CREATE TABLE statements.
func CreateTableStatements() []string {
	return []string{
		createAliasesTable(),
		createAttributesTable(),
		createBootactionTable(),
		createDistributionsTable(),
		createFirewallsTable(),
		createNetworksTable(),
		createPartitionsTable(),
		createPublicKeysTable(),
		createSoftwareTable(),
		createNodesTable(),
		createSubnetsTable(),
		createTrg_nodes_before_delete(),
	}
}

// DropTableOrder returns table names in reverse dependency order for safe DROP.
func DropTableOrder() []string {
	return []string{
		"aliases",
		"attributes",
		"bootactions",
		"distributions",
		"firewalls",
		"networks",
		"partitions",
		"publickeys",
		"software",
		"nodes",
		"subnets",
	}
}

func DropTriggerStatements() []string {
	return []string{
		"trg_nodes_before_delete",
	}
}

// --- Private DDL Functions ---
func createAliasesTable() string {
	return `
CREATE TABLE IF NOT EXISTS aliases (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    node_id INTEGER NOT NULL,
    alias TEXT NOT NULL,
    CONSTRAINT fk_aliases_node FOREIGN KEY(node_id) REFERENCES nodes(id),
    UNIQUE(node_id, alias)
);
create index if not exists idx_aliases_node on aliases (node_id);
`
}

func createAttributesTable() string {
	return `
CREATE TABLE IF NOT EXISTS attributes (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    node_id INTEGER NOT NULL,
    attr TEXT NOT NULL,
    value TEXT,
    shadow TEXT,
    CONSTRAINT fk_attributes_node FOREIGN KEY(node_id) REFERENCES nodes(id)
);
create index if not exists idx_attributes_node on attributes (node_id);
`
}

func createBootactionTable() string {
	return `
CREATE TABLE IF NOT EXISTS bootactions (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    node_id INTEGER NOT NULL,
    action TEXT,
    kernel TEXT,
    initrd TEXT,
    cmdline TEXT,
    CONSTRAINT fk_bootactions_node FOREIGN KEY(node_id) REFERENCES nodes(id),
    UNIQUE(node_id)
);
create index if not exists idx_bootactions_node on bootactions (node_id);
`
}

func createDistributionsTable() string {
	return `
CREATE TABLE IF NOT EXISTS distributions (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    node_id INTEGER,
    name TEXT NOT NULL,
    version TEXT,
    lang TEXT,
    os_release TEXT,
    constraint distributions_nodes_fk FOREIGN KEY(node_id) REFERENCES nodes(id)
);
create index if not exists idx_distributions_node on distributions (node_id);
`
}

func createFirewallsTable() string {
	return `
CREATE TABLE IF NOT EXISTS firewalls (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    node_id INTEGER,
    rulename TEXT NOT NULL,
    rulesrc TEXT NOT NULL,
    insubnet INTEGER,
    outsubnet INTEGER,
    service TEXT,
    protocol TEXT,
    action TEXT,
    chain TEXT,
    flags TEXT,
    comment TEXT,
    constraint firewalls_nodes_fk FOREIGN KEY(node_id) REFERENCES nodes(id)
);
create index if not exists idx_firewalls_node on firewalls (node_id);
`
}

func createNetworksTable() string {
	return `
CREATE TABLE IF NOT EXISTS networks (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    node_id INTEGER,
    subnet_id INTEGER,
    mac TEXT,
    ip TEXT,
    name TEXT,
    device TEXT,
    module TEXT,
    vlanid INTEGER,
    options TEXT,
    channel TEXT,
    disable_kvm INTEGER NOT NULL DEFAULT 0 CHECK (disable_kvm IN (0, 1)),
    constraint networks_nodes_fk FOREIGN KEY(node_id) REFERENCES nodes(id),
    constraint networks_subnets_fk FOREIGN KEY(subnet_id) REFERENCES subnets(id)
);
create index if not exists idx_networks_node on networks (node_id);
`
}

func createNodesTable() string {
	return `
CREATE TABLE IF NOT EXISTS nodes (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT NOT NULL,
    cpus INTEGER NOT NULL,
    rack INTEGER NOT NULL,
    rank INTEGER NOT NULL,
    arch TEXT,
    os TEXT,
    runaction TEXT,
    installaction TEXT
);
create index if not exists idx_nodes_name on nodes (name);
`
}

func createPartitionsTable() string {
	return `
CREATE TABLE IF NOT EXISTS partitions (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    node_id INTEGER,
    device TEXT NOT NULL,
    formatflags TEXT NOT NULL,
    fstype TEXT NOT NULL,
    mountpoint TEXT NOT NULL,
    partitionflags TEXT NOT NULL,
    partitionid TEXT NOT NULL,
    partitionsize TEXT NOT NULL,
    sectorstart TEXT NOT NULL,
    constraint partitions_nodes_fk FOREIGN KEY(node_id) REFERENCES nodes(id)
);
create index if not exists idx_partitions_node on partitions (node_id);
`
}

func createPublicKeysTable() string {
	return `
CREATE TABLE IF NOT EXISTS publickeys (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    node_id INTEGER,
    publickey TEXT NOT NULL,
    description TEXT,
    constraint publickeys_nodes_fk FOREIGN KEY(node_id) REFERENCES nodes(id)
);
create index if not exists idx_publickeys_node on publickeys (node_id);
`
}

func createSubnetsTable() string {
	return `
CREATE TABLE IF NOT EXISTS subnets (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT NOT NULL,
    dnszone TEXT NOT NULL,
    subnet TEXT NOT NULL,
    netmask TEXT NOT NULL,
    mtu INTEGER NOT NULL DEFAULT 1500,
    servedns INTEGER NOT NULL DEFAULT 0 CHECK (servedns IN (0, 1)),
    UNIQUE(name, dnszone)
);`
}

func createSoftwareTable() string {
	return `
CREATE TABLE IF NOT EXISTS software (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT NOT NULL,
    pathversion TEXT,
    fullversion TEXT,
    description TEXT,
    website TEXT,
    license TEXT,
    install_method TEXT NOT NULL CHECK (install_method IN (
        'source', 
        'binary',
        'rpm',
        'docker',
        'apptainer',
        'conda',
        'mamba',
        'spack',
        'tarball',
        'zipball',
        'pip',
        'npm',
        'custom'
        )),
    -- 源码编译相关参数
    source_url TEXT, -- 源码下载地址
    source_checksum TEXT, -- 源码校验和
    source_checksum_type TEXT NOT NULL CHECK (source_checksum_type IN (
        'md5',
        'sha1',
        'sha256',
        'sha512'
        )),
    build_dependencies TEXT,    -- 编译依赖(JSON格式)
    configure_params TEXT,      -- 配置参数(JSON格式)
    make_params TEXT,           -- make参数(JSON格式)
    make_install_params TEXT,   -- make install参数(JSON格式)

    -- 安装路径参数
    install_path TEXT NOT NULL, -- 安装路径
    env_vars TEXT,     -- 环境变量(JSON格式)

    -- 状态信息
    is_installed INTEGER NOT NULL DEFAULT 0 CHECK (is_installed IN (0, 1)), -- 是否安装
    install_date TEXT, -- 安装日期
    updated_date TEXT, -- 更新日期
    install_user TEXT, -- 安装用户
    notes TEXT,        -- 安装备注

    -- 元数据
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP, -- 创建时间
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, -- 更新时间

    UNIQUE(name)
);
create index if not exists idx_software_name on software (name);
create index if not exists idx_software_install_method on software (install_method);
create index if not exists idx_software_is_installed on software (is_installed);
`
}

func createTrg_nodes_before_delete() string {
	return `
CREATE TRIGGER IF NOT EXISTS trg_nodes_before_delete
    BEFORE DELETE ON nodes
    FOR EACH ROW
    BEGIN
        -- 先删除子表的关联记录
        DELETE FROM aliases WHERE node_id = OLD.id;
        DELETE FROM attributes WHERE node_id = OLD.id;
        DELETE FROM bootactions WHERE node_id = OLD.id;
        DELETE FROM distributions WHERE node_id = OLD.id;
        DELETE FROM firewalls WHERE node_id = OLD.id;
        DELETE FROM networks WHERE node_id = OLD.id;
        DELETE FROM partitions WHERE node_id = OLD.id;
        DELETE FROM publickeys WHERE node_id = OLD.id;
    END;
`
}
