const NULL_UUID = '00000000-0000-0000-0000-000000000000';

exports.up = async knex => {
    await knex.schema.createTable('games', table => {
        table.uuid('id').primary();
        table.index('id');
        table.timestamps(true, true);
        table.binary('data').notNullable();
    });

    await knex.schema.createTable('instances', async table => {
        table.uuid('id').primary();
        table.index('id');
        table.timestamps(true, true);

        table.binary('data').notNullable();
        table.boolean('open')
            .defaultTo(true)
            .notNullable();
    });

    await knex.schema.raw(
        // eslint-disable-next-line max-len
        'CREATE UNIQUE INDEX instances_open ON instances (open) WHERE open = true;'
    );


    await knex.schema.createTable('players', table => {
        table.uuid('id').primary();
        table.index('id');
        table.binary('data').notNullable();

        // the instance
        table.uuid('instance').notNullable()
        table.foreign('instance')
            .references('id')
            .inTable('instances')
            .onDelete('CASCADE');
        table.index('instance');

        // account in a game
        table.uuid('account').notNullable()
        table.foreign('account')
            .references('id')
            .inTable('accounts')
            .onDelete('CASCADE');
        table.index('account');

        table.unique(['account', 'instance']);

    });

    await knex.schema.createTable('matchmaking', async table => {
        table.uuid('id').primary();
        table.index('id');
        table.timestamps(true, true);

        table.uuid('game').notNullable()
        table.foreign('game')
            .references('id')
            .inTable('games')
            .onDelete('NO ACTION');
    });


    // not really sure if this is a good idea
    await knex('instances').insert({
        id: NULL_UUID,
        data: 'INVALID',
        open: false,
    });
};

exports.down = async () => {};