<?php
namespace install\services;
/**
 * Database creation service
 * @author Jérôme Brilland
 * @version 3.0
 * @copyright (c) 2019-2021, Jérôme Brilland
 * @license http://www.gnu.org/licenses/gpl.txt GNU General Public License
 */
class CreateDatabase {

    public function perform( $listener ) {
        try {
            $this->createSchema();
            $database = \IoC::resolve( 'database' );
            $error = $database->error();
            if ( $error[1] ) {
                $listener->createDatabaseFailed( $error[2] );
            }
        } catch ( \Exception $e ) {
            $listener->createDatabaseFailed( $e->getMessage() );
        }
    }

    protected function createSchema() {
        $schema = \IoC::resolve( 'sqlschema' );

        $schema->dropTableIfexists( 'page' );
        $schema->dropTableIfexists( 'template' );
        $schema->dropTableIfexists( 'snippet' );
        $schema->dropTableIfexists( 'role_permission' );
        $schema->dropTableIfexists( 'user_role' );
        $schema->dropTableIfexists( 'permission' );
        $schema->dropTableIfexists( 'user' );
        $schema->dropTableIfexists( 'role' );
        $schema->dropTableIfexists( 'tagging' );
        $schema->dropTableIfexists( 'tag' );
        $schema->dropTableIfexists( 'setting' );
        
        //template
        $schema->createTable( 'template', [
            'template_id' => ['integer', ['not_null' => true, 'primary_key' => true, 'identity' => true]],
            'name' => ['varchar', ['length' => 100, 'not_null' => true]],
            'content_type' => ['varchar', ['length' => 100, 'default'=> 'NULL']],
            'content' => ['clob', ['default'=> 'NULL']],
            'last_modified' => ['integer', ['not_null' => true]],
            'created_at' => ['datetime', ['not_null' => true]],
            'updated_at' => ['datetime', ['default' => 'NULL']]
        ] );
        $schema->addIndex( 'UX_template_name', 'template', 'name', true );
        
        //snippet  
        $schema->createTable( 'snippet', [
            'snippet_id' => ['integer', ['not_null' => true, 'primary_key' => true, 'identity' => true]],
            'name' => ['varchar', ['length' => 100, 'not_null' => true]],
            'language' => ['varchar', ['length' => 2, 'default'=> 'NULL']],
            'content' => ['clob', ['default'=> 'NULL']],
            'position' => ['integer', ['default' => 'NULL']],
            'created_at' => ['datetime', ['not_null' => true]],
            'updated_at' => ['datetime', ['default' => 'NULL']]
        ] );
        $schema->addIndex( 'UX_snippet_name', 'snippet', 'name', true );
        
        //page
        $schema->createTable( 'page', [
            'page_id' => ['integer', ['not_null' => true, 'primary_key' => true, 'identity' => true]],
            'title' => ['varchar', ['length' => 100, 'not_null' => true]],
            'description' => ['varchar', ['length' => 255, 'default'=> 'NULL']],
            'language' => ['varchar', ['length' => 2, 'default'=> 'NULL']],
            'slug' => ['varchar', ['length' => 100, 'default'=> 'NULL']],
            'content' => ['clob', ['default'=> 'NULL']],
            'parent_id' => ['integer', ['default' => 'NULL']],
            'template_id' => ['integer', ['default' => 'NULL']],
            'status' => ['smallint', ['not_null' => true]],
            'publication_date' => ['date', ['not_null' => true]],
            'publication_time' => ['time', ['not_null' => true]],
            'expiration_date' => ['date', ['default' => 'NULL']],
            'expiration_time' => ['time', ['default' => 'NULL']],
            'position' => ['integer', ['default' => 'NULL']],
            'created_at' => ['datetime', ['not_null' => true]],
            'updated_at' => ['datetime', ['default' => 'NULL']]
        ] );
        $schema->addIndex( 'UX_page_slug', 'page', 'slug', true );
        $schema->addForeignKey( 'FK_page_page', 'page', 'parent_id', 'page', 'page_id', 'CASCADE', 'CASCADE' );
        $schema->addForeignKey( 'FK_page_template', 'page', 'template_id', 'template', 'template_id', 'RESTRICT', 'CASCADE' );

        //permission
        $schema->createTable( 'permission', [
            'permission_id' => ['integer', ['not_null' => true, 'primary_key' => true, 'identity' => true]],
            'name' => ['varchar', ['length' => 100, 'not_null' => true]],
            'description' => ['text']
        ] );
        $schema->addIndex( 'UX_permission_name', 'permission', 'name', true );
  
        //role
        $schema->createTable( 'role', [
            'role_id' => ['integer', ['not_null' => true, 'primary_key' => true, 'identity' => true]],
            'name' => ['varchar', ['length' => 100, 'not_null' => true]],
            'description' => ['text']
        ] );
        $schema->addIndex( 'UX_role_name', 'role', 'name', true );

        //role_permission
        $schema->createTable( 'role_permission', [
            'role_permission_id' => ['integer', ['not_null' => true, 'primary_key' => true, 'identity' => true]],
            'role_id' => ['integer', ['not_null' => true]],
            'permission_id' => ['integer', ['not_null' => true]]
        ] );
        $schema->addIndex( 'UX_role_permission_role_id_permission_id', 'role_permission', ['role_id', 'permission_id'], true );
        $schema->addForeignKey( 'FK_role_permission_permission', 'role_permission', 'permission_id', 'permission', 'permission_id', 'CASCADE', 'CASCADE' );
        $schema->addForeignKey( 'FK_role_permission_role', 'role_permission', 'role_id', 'role', 'role_id', 'CASCADE', 'CASCADE' );

        //user
        $schema->createTable( 'user', [
            'user_id' => ['integer', ['not_null' => true, 'primary_key' => true, 'identity' => true]],
            'username' => ['varchar', ['length' => 100, 'not_null' => true]],
            'encrypted_password' => ['varchar', ['length' => 255, 'not_null' => true]],
            'email' => ['varchar', ['length' => 255, 'not_null' => true]],
            'last_login' => ['datetime', ['default' => 'NULL']],
            'status' => ['smallint', ['not_null' => true]],
            'preferences' => ['clob', ['default'=> 'NULL']],
            'activation_token' => ['varchar', ['length' => 255, 'default' => 'NULL']],
            'password_reset_token' => ['varchar', ['length' => 255, 'default' => 'NULL']],
            'password_reset_sent_at' => ['datetime', ['default' => 'NULL']],
            'created_at' => ['datetime', ['not_null' => true]],
            'updated_at' => ['datetime', ['default' => 'NULL']]
        ] );

        //user_role
        $schema->createTable( 'user_role', [
            'user_role_id' => ['integer', ['not_null' => true, 'primary_key' => true, 'identity' => true]],
            'user_id' => ['integer', ['not_null' => true]],
            'role_id' => ['integer', ['not_null' => true]]
        ] );
        $schema->addIndex( 'UX_user_role_user_id_role_id', 'user_role', ['user_id', 'role_id'], true );
        $schema->addForeignKey( 'FK_user_role_role', 'user_role', 'role_id', 'role', 'role_id', 'CASCADE', 'CASCADE' );
        $schema->addForeignKey( 'FK_user_role_user', 'user_role', 'user_id', 'user', 'user_id', 'CASCADE', 'CASCADE' );

        //tag
        $schema->createTable( 'tag', [
            'tag_id' => ['integer', ['not_null' => true, 'primary_key' => true, 'identity' => true]],
            'name' => ['varchar', ['length' => 100, 'not_null' => true]],
            'created_at' => ['datetime', ['not_null' => true]],
            'updated_at' => ['datetime', ['default' => 'NULL']]
        ] );
        $schema->addIndex( 'UX_tag_name', 'tag', 'name', true );

        //tagging
        $schema->createTable( 'tagging', [
            'tagging_id' => ['integer', ['not_null' => true, 'primary_key' => true, 'identity' => true]],
            'tag_id' => ['integer', ['not_null' => true]],
            'taggable_type' => ['varchar', ['length' => 100, 'not_null' => true]],
            'taggable_id' => ['integer', ['not_null' => true]]
        ] );
        $schema->addForeignKey( 'FK_tagging_tag', 'tagging', 'tag_id', 'tag', 'tag_id', 'CASCADE', 'CASCADE' );
        $schema->addIndex( 'IX_tagging_taggable_id', 'tagging', 'taggable_id', false );
            
        //setting
        $schema->createTable( 'setting', [
            'setting_id' => ['integer', ['not_null' => true, 'primary_key' => true, 'identity' => true]],
            'name' => ['varchar', ['length' => 100, 'not_null' => true]],
            'value' => ['text']
        ] );
        $schema->addIndex( 'UX_setting_name', 'setting', 'name', true );
    }
}
