-- nodes
drop table if exists nodes cascade;
create table nodes (
    id         serial primary key,
    name       varchar(255) not null unique,
    version    int          not null,
    fwd_port   int          not null,
    provider   varchar(255) not null,
    location   varchar(255) not null,
    created_at timestamp default current_timestamp,
    updated_at timestamp default current_timestamp,
    deleted_at timestamp
);
create index devices_provider_index on nodes (provider);
create index devices_location_index on nodes (location);

-- users
drop table if exists users cascade;
create table users (
    id         serial primary key,
    password   varchar(255) not null,
    username   varchar(255) not null unique,
    email      varchar(255) not null unique,
    phone      varchar(255) not null unique,
    name       varchar(255) not null,
    created_at timestamp default current_timestamp,
    updated_at timestamp default current_timestamp,
    deleted_at timestamp
);

-- user_ips
drop table if exists user_ips cascade;
create table user_ips (
    id         serial primary key,
    user_id    int          not null references users (id)
        on update cascade
        on delete cascade,
    ip_address varchar(255) not null,
    created_at timestamp default current_timestamp,
    updated_at timestamp default current_timestamp,
    deleted_at timestamp
);
create index user_ips_user_id_index on user_ips (user_id);
create index user_ips_ip_address_index on user_ips (ip_address);

-- channel
drop table if exists channels cascade;
create table channels (
    id         serial primary key,
    user_id    int          not null references users (id)
        on update cascade
        on delete cascade,
    node_id    int          not null references nodes (id) --
        on update cascade                                  --
        on delete set null,                                -- 节点删除后，用户侧需要保留提取记录
    user_addr  varchar(255) not null,                      -- 快照数据
    node_port  int,                                        -- 快照数据
    auth_ip    bool,
    auth_pass  bool,
    protocol   varchar(255),
    username   varchar(255) unique,
    password   varchar(255),
    expiration timestamp    not null,
    created_at timestamp default current_timestamp,
    updated_at timestamp default current_timestamp,
    deleted_at timestamp
);
create index channel_user_id_index on channels (user_id);
create index channel_node_id_index on channels (node_id);
create index channel_user_addr_index on channels (user_addr);
create index channel_node_port_index on channels (node_port);

-- ====================
-- 填充数据
-- ====================

do
$$
    declare
        r_user_id int;
        r_node_id int;
    begin
        -- 用户信息
        insert into users (
            username, password, email, phone, name
        )
        values (
            'test', 'test', 'test@user.email', '12345678901', 'test_user'
        )
        returning id into r_user_id;

        insert into user_ips (
            user_id, ip_address
        )
        values (
            r_user_id, '::1'
        ), (
            r_user_id, '127.0.0.1'
        );

        -- 节点信息
        insert into nodes (
            name, version, fwd_port, provider, location
        )
        values (
            'qwer', 1, 20001, 'test_provider', 'test_location'
        )
        returning id into r_node_id;

        -- 权限信息
        insert into channels (
            user_id, node_id, user_addr, node_port, auth_ip, auth_pass,
            protocol, username, password, expiration
        )
        values (
            r_user_id, r_node_id, '::1', 20001, true, false,
            'http', 'ip6http', 'asdf', now() + interval '1 year'
        ), (
            r_user_id, r_node_id, '::1', 20001, true, false,
            'socks5', 'ip6socks', 'asdf', now() + interval '1 year'
        ), (
            r_user_id, r_node_id, '127.0.0.1', 20001, true, false,
            'http', 'ip4http', 'asdf', now() + interval '1 year'
        ), (
            r_user_id, r_node_id, '127.0.0.1', 20001, true, false,
            'socks5', 'ip4socks', 'asdf', now() + interval '1 year'
        );
    end
$$;
