-- +goose Up
START TRANSACTION;

CREATE SCHEMA IF NOT EXISTS auth;

CREATE TABLE IF NOT EXISTS auth.account (
	id SERIAL PRIMARY KEY,
	createdTs TIMESTAMP NOT NULL DEFAULT NOW(),
	verifiedTs TIMESTAMP NULL,
	email VARCHAR(512) NOT NULL,
	passwordHash VARCHAR(512) NOT NULL,
	role VARCHAR(64) NOT NULL DEFAULT 'bidder',
	enabled BIT NOT NULL DEFAULT 1
);

CREATE TABLE IF NOT EXISTS auth.account_verification (
	id SERIAL PRIMARY KEY,
	accountId INT NOT NULL,
	createdTs TIMESTAMP NOT NULL DEFAULT NOW(),
	verificationToken VARCHAR(128) NOT NULL UNIQUE,
	CONSTRAINT fk_account_id FOREIGN KEY (accountId) REFERENCES auth.account(id) ON DELETE CASCADE
);

CREATE TABLE IF NOT EXISTS auth.sessions (
	id SERIAL PRIMARY KEY,
	accountId INT NOT NULL,
	createdTs TIMESTAMP NOT NULL DEFAULT NOW(),
	CONSTRAINT fk_account_id FOREIGN KEY (accountId) REFERENCES auth.account(id) ON DELETE CASCADE
);

-- +goose StatementBegin
CREATE OR REPLACE FUNCTION auth.bh_register_account(
    p_email    VARCHAR(512),
    p_passwordHash    VARCHAR(512),
	p_role VARCHAR(64))
RETURNS INTEGER
LANGUAGE plpgsql AS $BODY$
DECLARE
	account_id INTEGER;
BEGIN
    SELECT acc.id INTO account_id FROM auth.account acc WHERE acc.email = p_email;

	IF account_id IS NULL OR account_id = 0 THEN
        INSERT INTO auth.account (
			email,
			password,
			role,
			enabled
		) VALUES (
			p_email,
			p_passwordHash,
			p_role,
			p_enabled
		) RETURNING id INTO account_id;
    ELSE
		-- 0 means there is a duplicate account
	    account_id = 0;
	END IF;

	RETURN account_id;
END;
$BODY$;
-- +goose StatementEnd

-- +goose StatementBegin
CREATE OR REPLACE FUNCTION auth.bh_verify_account(
    p_verification_token    VARCHAR(128))
RETURNS INTEGER
LANGUAGE plpgsql AS $BODY$
DECLARE
	account_id INTEGER;
	verification_id INTEGER;
BEGIN
    SELECT
		acc.id INTO account_id,
		ev.id INTO verification_id
	FROM auth.account acc
		JOIN auth.account_verification ev ON acc.id = ev.accountId
		WHERE ev.verificationToken = p_verification_token;

	IF account_id IS NULL OR account_id = 0 THEN
		-- 0 means there is a duplicate account
	    account_id = 0;
    ELSE
		UPDATE auth.account SET verifiedTs=NOW() WHERE id = account_id;
		DELETE FROM auth.account_verification WHERE id = verification_id;
	END IF;

	RETURN account_id;
END;
$BODY$;
-- +goose StatementEnd




-- +goose StatementBegin
DO
$do$
BEGIN
   IF NOT EXISTS (
      SELECT FROM pg_catalog.pg_roles
      WHERE rolname = 'auth-service') THEN

		CREATE USER "auth-service" WITH PASSWORD 'auth-service';
   END IF;
END
$do$;
-- +goose StatementEnd

GRANT CONNECT ON DATABASE bh to "auth-service";
GRANT USAGE ON SCHEMA auth TO "auth-service";
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA auth TO "auth-service";
GRANT SELECT, INSERT, UPDATE ON ALL TABLES IN SCHEMA auth TO "auth-service";

COMMIT;

-- +goose Down
