-- so we can default uuid fields using uuid_generate_v4. nice to have.
CREATE EXTENSION "uuid-ossp";

CREATE TABLE users (
    id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(),
    name VARCHAR(50) NOT NULL,
    email VARCHAR(255) NOT NULL UNIQUE,
    remember_token VARCHAR(255) UNIQUE,
    password_digest VARCHAR(255) NOT NULL,
    admin boolean NOT NULL DEFAULT false,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX remember_token_idx ON users(remember_token);

-- adhoc jam sessions
CREATE TABLE jam_sessions (
    id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(),
    name VARCHAR(8000),
    public boolean NOT NULL DEFAULT true,
    user_id VARCHAR(64) NOT NULL REFERENCES users(id),
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

-- users currently in the jam session
CREATE TABLE jam_session_members (
    id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(),
    user_id VARCHAR(64) REFERENCES users(id) ON DELETE CASCADE,
    jam_session_id VARCHAR(64) REFERENCES jam_sessions(id) ON DELETE CASCADE,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

ALTER TABLE jam_session_members ADD CONSTRAINT user_jam_session_uniqkey UNIQUE (user_id, jam_session_id);

CREATE TABLE connections (
    id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(),
    user_id VARCHAR(64) REFERENCES users(id) ON DELETE CASCADE,
    client_id VARCHAR(64) NOT NULL UNIQUE,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

-- friendships
CREATE TABLE friendships (
    id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(),
    user_id VARCHAR(64) REFERENCES users(id) ON DELETE CASCADE,
    friend_id VARCHAR(64) REFERENCES users(id) ON DELETE CASCADE,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

ALTER TABLE friendships ADD CONSTRAINT user_friend_uniqkey UNIQUE (user_id, friend_id);

-- bands
CREATE TABLE bands (
    id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(),
    name VARCHAR(1024) NOT NULL,
    -- add more fields later
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

-- genres
CREATE TABLE genres (
    id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(),
    description VARCHAR(1024) NOT NULL,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

-- band -> genre mapping
CREATE TABLE bands_genres (
    id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(),
    band_id VARCHAR(64) REFERENCES bands(id) ON DELETE CASCADE,
    genre_id VARCHAR(64) REFERENCES genres(id) ON DELETE CASCADE,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

ALTER TABLE bands_genres ADD CONSTRAINT band_genre_uniqkey UNIQUE (band_id, genre_id);

-- musicians
CREATE TABLE musicians (
    id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(),
    user_id VARCHAR(64) REFERENCES users(id) ON DELETE CASCADE,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

-- musician -> band mapping
CREATE TABLE bands_musicians (
    id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(),
    band_id VARCHAR(64) REFERENCES bands(id) ON DELETE CASCADE,
    musician_id VARCHAR(64) REFERENCES musicians(id) ON DELETE CASCADE,
    is_admin BOOLEAN NOT NULL DEFAULT false,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

ALTER TABLE bands_musicians ADD CONSTRAINT band_musician_uniqkey UNIQUE (band_id, musician_id);

-- instruments
CREATE TABLE instruments (
    id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(),
    description VARCHAR(1024) NOT NULL,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

-- musician -> instrument mapping
CREATE TABLE musicians_instruments (
    id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(),
    musician_id VARCHAR(64) REFERENCES musicians(id) ON DELETE CASCADE,
    instrument_id VARCHAR(64) REFERENCES instruments(id) ON DELETE CASCADE,
    proficiency_level SMALLINT NOT NULL,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

ALTER TABLE musicians_instruments ADD CONSTRAINT musician_instrument_uniqkey UNIQUE (musician_id, instrument_id);

-- create a utility method to truncate all tables

CREATE OR REPLACE FUNCTION truncate_tables() RETURNS void AS $$
DECLARE
    statements CURSOR FOR
        SELECT tablename FROM pg_tables
        WHERE schemaname = 'public';
BEGIN
    FOR stmt IN statements LOOP
        EXECUTE 'TRUNCATE TABLE ' || quote_ident(stmt.tablename) || ' CASCADE;';
    END LOOP;
END;
$$ LANGUAGE plpgsql;

-- create a utility that bootstraps a user
CREATE OR REPLACE FUNCTION bootstrap_users() RETURNS void AS $$
DECLARE

BEGIN
	-- non guid used for test user.  test user won't be in actual database, but '1' is much easier to script that 242423-42-4-24234
	-- password is jam123
	INSERT INTO users (id, name, email, remember_token, password_digest) VALUES ('1', 'test', 'test@jamkazam.com', 'NQubl-z16Em94tnSdofObw', '$2a$10$QyaNTLVX5DAaJ.JL21kDWeUQqdh3Qh7JQbdRgE82x1Cib7HWNcHXC');
END;
$$ LANGUAGE plpgsql;

select bootstrap_users();

