<?php
/**
 * Copyright © 2015 FiloBlu. All rights reserved.
 */

namespace FiloBlu\Flow\Setup;

use Exception;
use Magento\Framework\DB\Ddl\Table;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
use Magento\Framework\Setup\UpgradeSchemaInterface;
use Zend_Db_Exception;

/**
 * @codeCoverageIgnore
 */
class UpgradeSchema implements UpgradeSchemaInterface
{
    const FLOW_DOCUMENT_TABLE = 'flow_document';
    const FLOW_SWATCH_TABLE = 'flow_swatch';
    const FLOW_VIDEO_TABLE = 'flow_videosflow';
    const FLOW_STOCK_ADJUSTMENT_TABLE = 'flow_from_stock_adjustment';

    /**
     * {@inheritdoc}
     * @throws Exception
     */
    public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        $setup->startSetup();

        if (version_compare($context->getVersion(), '0.0.8') < 0) {
            $this->createFlowFromStockTable($setup, $context);
        }

        if (version_compare($context->getVersion(), '0.1.1') < 0) {
            $this->addImagesTable($setup, $context);
        }

        if (version_compare($context->getVersion(), '0.1.2') < 0) {
            $this->addUniqueConstraints($setup, $context);
        }

        if (version_compare($context->getVersion(), '0.1.3') < 0) {
            $this->addMetaFileToStock($setup, $context);
        }

        if (version_compare($context->getVersion(), '0.1.6') < 0) {
            $this->addProcessImagesTables($setup, $context);
        }

        if (version_compare($context->getVersion(), '0.2.1') < 0) {
            $this->addImagesHideColumn($setup, $context);
        }

        if (version_compare($context->getVersion(), '0.4.5') < 0) {
            $this->addUniqueConstraints2($setup, $context);
        }

        if (version_compare($context->getVersion(), '1.0.0') < 0) {
            $this->addColumnsToIte($setup, $context);
        }

        if (version_compare($context->getVersion(), '1.0.1') < 0) {
            $this->addVisibilityToIte($setup, $context);
        }

        if (version_compare($context->getVersion(), '1.0.2') < 0) {
            $this->changeCodConfigurableLength($setup, $context);
        }

        if (version_compare($context->getVersion(), '1.0.3') < 0) {
            $this->addExecutedOnField($setup, $context);
        }

        if (version_compare($context->getVersion(), '1.0.4') < 0) {
            $this->addLanguageFieldOnEavs($setup, $context);
        }

        if (version_compare($context->getVersion(), '1.0.5') < 0) {
            $this->addAttributeSetOnIte($setup, $context);
        }

        if (version_compare($context->getVersion(), '1.0.6') < 0) {
            $this->changeFasciaIvaArticoliLength($setup, $context);
        }

        if (version_compare($context->getVersion(), '1.0.7') < 0) {
            $this->createLogTable($setup);
        }

        if (version_compare($context->getVersion(), '1.0.8') < 0) {
            $this->createDocumentTable($setup);
        }

        if (version_compare($context->getVersion(), '1.0.9') < 0) {
            $this->createBundleTable($setup);
        }

        if (version_compare($context->getVersion(), '1.0.10') < 0) {
            $this->createSubscribersTable($setup, $context);
        }

        if (version_compare($context->getVersion(), '1.0.11') < 0) {
            $this->addStockCompensationColumns($setup, $context);
        }

        if (version_compare($context->getVersion(), '1.0.12') < 0) {
            $this->createSwatchTable($setup, $context);
        }

        if (version_compare($context->getVersion(), '1.0.12') <= 0) {
            $this->addVideosTable($setup, $context);
        }

        if (version_compare($context->getVersion(), '1.0.14') <= 0) {
            $this->addLookupSkuColumn($setup);
        }

        if (version_compare($context->getVersion(), '1.0.15') <= 0) {
            $this->addIndexes($setup);
        }

        if (version_compare($context->getVersion(), '1.0.17') <= 0) {
            $this->extendsInboundFlow($setup, $context);
        }

        if (version_compare($context->getVersion(), '1.0.18') <= 0) {
            $this->createStockAdjustmentTable($setup, $context);
        }

        if (version_compare($context->getVersion(), '1.0.19') < 0) {
            $this->changePaeseSkuLength($setup, $context);
        }

        if (version_compare($context->getVersion(), '1.0.20') < 0) {
            $this->addGroupedTable($setup, $context);
        }

        if (version_compare($context->getVersion(), '1.0.21') < 0) {
            $this->createSizeguideTable($setup, $context);
        }

        if (version_compare($context->getVersion(), '1.0.22') < 0) {
            $this->addSharedCatalogTable($setup, $context);
            $this->addSharedCatalogPricesTable($setup, $context);
        }

        if (version_compare($context->getVersion(), '1.0.24') < 0) {
            $this->addEavsGroupedTable($setup, $context);
        }

        if (version_compare($context->getVersion(), '1.0.25') < 0) {
            $this->updateBundleTable($setup);
        }

        if (version_compare($context->getVersion(), '1.0.26') < 0) {
            $this->addSwatchColorsTable($setup);
        }

        if (version_compare($context->getVersion(), '1.0.27') < 0) {
            $this->fixReceivingTimeColumn($setup);
            $this->createFlowFromCustomerTable($setup, $context);
        }

        $setup->endSetup();
    }

    /**
     * @param SchemaSetupInterface $setup
     * @param ModuleContextInterface $context
     * @throws Zend_Db_Exception
     */
    public function createFlowFromStockTable(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        /**
         * Create table 'flow_from_stock' if not exists
         */

        if (!$setup->tableExists('flow_from_stock')) {
            $table = $setup->getConnection()->newTable(
                $setup->getTable('flow_from_stock')
            )->addColumn(
                    'sku',
                    Table::TYPE_TEXT,
                    '40',
                    [],
                    'sku'
                )->addColumn(
                    'magazzino',
                    Table::TYPE_TEXT,
                    '30',
                    [],
                    'magazzino'
                )->addColumn(
                    'fisico_disponibile',
                    Table::TYPE_INTEGER,
                    '10',
                    [],
                    'qta disponibile in magazzino - aggiornamento in sovrascrittura'
                )->addColumn(
                    'meta_id',
                    Table::TYPE_INTEGER,
                    null,
                    ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
                    'id'
                )->addColumn(
                    'meta_ref_id',
                    Table::TYPE_INTEGER,
                    '11',
                    [],
                    'meta_ref_id'
                )->addColumn(
                    'meta_processed',
                    Table::TYPE_INTEGER,
                    '1',
                    [],
                    'meta_processed'
                )->addColumn(
                    'meta_process_time',
                    Table::TYPE_DATETIME,
                    '10',
                    [],
                    'meta_process_time'
                )->setComment(
                    'FiloBlu Flow flow_from_stock'
                );

            $setup->getConnection()->createTable($table);
        }
    }

    /**
     * @param $setup
     * @param $context
     */
    public function addImagesTable($setup, $context)
    {
        /**
         * Create table 'filoblu_imageflow_from' if not exists
         */

        if (!$setup->tableExists('flow_imagesflow')) {
            $table = $setup->getConnection()->newTable(
                $setup->getTable('flow_imagesflow')
            )->addColumn(
                    'id',
                    Table::TYPE_INTEGER,
                    null,
                    ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
                    null
                )->addColumn(
                    'image_name',
                    Table::TYPE_TEXT,
                    '64k',
                    [],
                    null
                )->addColumn(
                    'image_status',
                    Table::TYPE_TEXT,
                    '30',
                    [],
                    null
                )->addColumn(
                    'image_queue_time',
                    Table::TYPE_DATETIME,
                    null,
                    [],
                    null
                )->addColumn(
                    'image_receive_time',
                    Table::TYPE_DATETIME,
                    null,
                    [],
                    null
                )->addColumn(
                    'image_process_time',
                    Table::TYPE_DATETIME,
                    null,
                    [],
                    null
                )->addColumn(
                    'meta_file',
                    Table::TYPE_INTEGER,
                    null,
                    ['nullable' => false],
                    null
                )->addColumn(
                    'meta_processed',
                    Table::TYPE_SMALLINT,
                    '1',
                    ['nullable' => false, 'default' => '0'],
                    null
                )->addColumn(
                    'log',
                    Table::TYPE_TEXT,
                    '64k',
                    [],
                    null
                );

            /*{{CedAddTableColumn}}}*/
            $setup->getConnection()->createTable($table);
            /*{{CedAddTable}}*/
        }
    }

    /**
     * @param SchemaSetupInterface $setup
     * @param ModuleContextInterface $context
     * @throws Exception
     */
    public function addUniqueConstraints(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        try {
            $setup->getConnection()->query('ALTER TABLE `flow_inboundflow` ADD UNIQUE (`name`(255));');
            $setup->getConnection()->query('ALTER TABLE `flow_channels` ADD UNIQUE (`name`(40));');
        } catch (Exception $e) {
            throw new Exception(
                'Error Processing Request - add unique constraints on `flow_inboundflow` and `flow_channels` ' . $e->getMessage(
                ), 1
            );
        }
    }

    /**
     * @param SchemaSetupInterface $setup
     * @param ModuleContextInterface $context
     */
    public function addMetaFileToStock(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        if ($setup->tableExists('flow_from_stock')) {
            $setup->getConnection()->addColumn(
                    $setup->getTable('flow_from_stock'), 'meta_file', [
                        'type'     => Table::TYPE_INTEGER,
                        'nullable' => false,
                        'comment'  => 'meta_file',
                        'after'    => 'meta_id'
                    ]
                );
        }
    }

    /**
     * @param SchemaSetupInterface $setup
     * @param ModuleContextInterface $context
     */
    public function addProcessImagesTables(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        if ($setup->tableExists('flow_imagesflow')) {
            $setup->getConnection()->addColumn(
                    $setup->getTable('flow_imagesflow'), 'image_sku', [
                        'type'     => Table::TYPE_TEXT,
                        'length'   => '100',
                        'nullable' => false,
                        'comment'  => 'image_sku',
                        'after'    => 'image_name'
                    ]
                );
            $setup->getConnection()->addColumn(
                    $setup->getTable('flow_imagesflow'), 'image_position', [
                        'type'     => Table::TYPE_TEXT,
                        'length'   => '10',
                        'nullable' => false,
                        'comment'  => 'image_position',
                        'after'    => 'image_name'
                    ]
                );
            $setup->getConnection()->addColumn(
                    $setup->getTable('flow_imagesflow'), 'image_path', [
                        'type'     => Table::TYPE_TEXT,
                        'length'   => '64k',
                        'nullable' => false,
                        'comment'  => 'image_path',
                        'after'    => 'image_name'
                    ]
                );
            $setup->getConnection()->addColumn(
                    $setup->getTable('flow_imagesflow'), 'image_alt', [
                        'type'     => Table::TYPE_TEXT,
                        'length'   => '255',
                        'nullable' => true,
                        'comment'  => 'image_alt',
                        'after'    => 'image_name'
                    ]
                );
            $setup->getConnection()->addColumn(
                    $setup->getTable('flow_imagesflow'), 'image_type', [
                        'type'     => Table::TYPE_TEXT,
                        'length'   => '50',
                        'nullable' => false,
                        'comment'  => 'image_type',
                        'after'    => 'image_name'
                    ]
                );
        }
    }

    /**
     * @param SchemaSetupInterface $setup
     * @param ModuleContextInterface $context
     */
    public function addImagesHideColumn(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        if ($setup->tableExists('flow_imagesflow')) {
            $setup->getConnection()->addColumn(
                    $setup->getTable('flow_imagesflow'), 'image_hide', [
                        'type'     => Table::TYPE_TEXT,
                        'length'   => '10',
                        'nullable' => false,
                        'comment'  => 'image_hide',
                        'after'    => 'image_name'
                    ]
                );
        }
    }

    /**
     * @param SchemaSetupInterface $setup
     * @param ModuleContextInterface $context
     * @throws Exception
     */
    public function addUniqueConstraints2(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
//        try {
//            $setup->getConnection()->query("ALTER TABLE `flow_from_eavs` ADD UNIQUE INDEX `IDX_E_A_V_S_METAFILE` (`e`, `a`, `v`(100), `s`, `meta_file`);");
//        } catch (\Exception $e) {
//            throw new \Exception("Error Processing Request - add unique constraints on `flow_from_eavs` : " . $e->getMessage(), 1);
//        }
    }

    /**
     * @param SchemaSetupInterface $setup
     * @param ModuleContextInterface $context
     */
    public function addColumnsToIte(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        if ($setup->tableExists('flow_from_ite')) {
            $setup->getConnection()->addColumn(
                    $setup->getTable('flow_from_ite'), 'configurable_values', [
                        'type'     => Table::TYPE_TEXT,
                        'length'   => 150,
                        'nullable' => true,
                        'after'    => 'codice_configurabile',
                        'comment'  => 'Attributes needed to create the configurable'
                    ]
                );

            $setup->getConnection()->addColumn(
                    $setup->getTable('flow_from_ite'), 'configurable_attributes', [
                        'type'     => Table::TYPE_TEXT,
                        'length'   => 200,
                        'nullable' => true,
                        'after'    => 'codice_configurabile',
                        'comment'  => 'Attributes needed to create the configurable'
                    ]
                );
        }
    }

    /**
     * @param SchemaSetupInterface $setup
     * @param ModuleContextInterface $context
     */
    public function addVisibilityToIte(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        if ($setup->tableExists('flow_from_ite')) {
            $setup->getConnection()->addColumn(
                    $setup->getTable('flow_from_ite'), 'visibility', [
                        'type'     => Table::TYPE_TEXT,
                        'length'   => 10,
                        'nullable' => true,
                        'after'    => 'fascia_iva_articoli',
                        'comment'  => 'Visibility of the product, not mandatory'
                    ]
                );
        }
    }

    /**
     * @param SchemaSetupInterface $setup
     * @param ModuleContextInterface $context
     * @throws Exception
     */
    public function changeCodConfigurableLength(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        try {
            $setup->getConnection()->query(
                "ALTER TABLE `flow_from_ite` CHANGE COLUMN `codice_configurabile` `codice_configurabile` VARCHAR(255) NULL DEFAULT NULL COMMENT 'codice_configurabile'"
            );
        } catch (Exception $e) {
            throw new Exception('Error Altering table `flow_from_ite` : ' . $e->getMessage(), 1);
        }
    }

    /**
     * @param SchemaSetupInterface $setup
     * @param ModuleContextInterface $context
     */
    public function addExecutedOnField(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        if ($setup->tableExists('flow_from_eavs')) {
            $setup->getConnection()->addColumn(
                    $setup->getTable('flow_from_eavs'), 'executed_on', [
                        'type'     => Table::TYPE_TEXT,
                        'length'   => '25',
                        'nullable' => true,
                        'comment'  => 'executed_on',
                        'after'    => 'meta_ref_id'
                    ]
                );
        }
    }

    /**
     * @param SchemaSetupInterface $setup
     * @param ModuleContextInterface $context
     * @throws Exception
     */
    public function addLanguageFieldOnEavs(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        try {
            $setup->getConnection()->query(
                "ALTER TABLE `flow_from_eavs` ADD COLUMN `l` VARCHAR(20) NULL DEFAULT NULL COMMENT 'l' AFTER `s`"
            );
        } catch (Exception $e) {
            throw new Exception('Error Altering table `flow_from_eavs` : ' . $e->getMessage(), 1);
        }
    }

    /**
     * @param SchemaSetupInterface $setup
     * @param ModuleContextInterface $context
     */
    public function addAttributeSetOnIte(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        if ($setup->tableExists('flow_from_ite')) {
            $setup->getConnection()->addColumn(
                    $setup->getTable('flow_from_ite'), 'attribute_set', [
                        'type'     => Table::TYPE_TEXT,
                        'length'   => 25,
                        'nullable' => true,
                        'after'    => 'visibility',
                        'comment'  => 'Attribute Set of the product, not mandatory'
                    ]
                );
        }
    }

    /**
     * @param SchemaSetupInterface $setup
     * @param ModuleContextInterface $context
     * @throws Exception
     */
    public function changeFasciaIvaArticoliLength(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        try {
            $setup->getConnection()->query(
                "ALTER TABLE `flow_from_ite` CHANGE COLUMN `fascia_iva_articoli` `fascia_iva_articoli` VARCHAR(100) NULL DEFAULT NULL COMMENT 'fascia_iva_articoli'"
            );
        } catch (Exception $e) {
            throw new Exception('Error Altering table `flow_from_ite` : ' . $e->getMessage(), 1);
        }
    }

    /**
     * @param SchemaSetupInterface $installer
     * @throws Zend_Db_Exception
     */
    protected function createLogTable(SchemaSetupInterface $installer)
    {
        /**
         * Create table 'flow_log' if not exists
         */
        if ($installer->tableExists('flow_log')) {
            return;
        }

        $logTable = $installer->getConnection()->newTable(
            $installer->getTable('flow_log')
        )->addColumn(
                'id',
                Table::TYPE_INTEGER,
                null,
                ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
                'Flow log table'
            )->addColumn(
                'message',
                Table::TYPE_TEXT,
                '1024',
                [],
                'Human readable message'
            )->addColumn(
                'stack_trace',
                Table::TYPE_TEXT,
                '64k',
                [],
                'Stacktrace'
            )->addColumn(
                'stack_trace_hash',
                Table::TYPE_TEXT,
                '200',
                ['nullable' => false],
                'Stack Trace hash md5'
            )->addColumn(
                'error_severity',
                Table::TYPE_TEXT,
                '200',
                ['nullable' => false],
                'Error severity'
            )->addColumn(
                'error_repeat_count',
                Table::TYPE_INTEGER,
                null,
                ['unsigned' => true, 'nullable' => false, 'default' => 1],
                'Error repeat count'
            )->addColumn(
                'meta_file',
                Table::TYPE_INTEGER,
                null,
                ['unsigned' => true, 'nullable' => true],
                'Inbound Flow file'
            )->addColumn(
                'meta_insert_time',
                Table::TYPE_DATETIME,
                '10',
                ['unsigned' => true, 'nullable' => false],
                'meta_insert_time'
            )->addForeignKey(
                $installer->getFkName(
                    'flow_log',
                    'meta_file',
                    'flow_inboundflow',
                    'id'
                ),
                'meta_file',
                $installer->getTable('flow_inboundflow'),
                'id',
                Table::ACTION_CASCADE
            );

        $installer->getConnection()->createTable($logTable);
    }

    /**
     * @param SchemaSetupInterface $installer
     * @throws Zend_Db_Exception
     */
    protected function createDocumentTable(SchemaSetupInterface $installer)
    {
        /**
         * Create table 'flow_document' if not exists
         */
        if ($installer->tableExists(self::FLOW_DOCUMENT_TABLE)) {
            return;
        }

        $documentTable = $installer->getConnection()->newTable(
            $installer->getTable(self::FLOW_DOCUMENT_TABLE)
        )->addColumn(
            'id',
            Table::TYPE_INTEGER,
            null,
            ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
            'Document Id'
        )->addColumn(
            'name',
            Table::TYPE_TEXT,
            '255',
            ['nullable' => false],
            'Document Name'
        )->addColumn(
            'mime',
            Table::TYPE_TEXT,
            '50',
            [],
            'Document Mime'
        )->addColumn(
            'source',
            Table::TYPE_TEXT,
            '255',
            [],
            'Document Source'
        )->addColumn(
            'destination',
            Table::TYPE_TEXT,
            '255',
            [],
            'Document Destination'
        )->addColumn(
            'status',
            Table::TYPE_TEXT,
            '50',
            [],
            'Status'
        )->addColumn(
            'log',
            Table::TYPE_TEXT,
            '64k',
            [],
            'Document Log'
        )->addColumn(
            'meta_file',
            Table::TYPE_INTEGER,
            null,
            ['unsigned' => true, 'nullable' => false],
            'Inbound Flow file'
        )->addColumn(
            'meta_insert_time',
            Table::TYPE_DATETIME,
            '10',
            ['unsigned' => true, 'nullable' => false],
            'Meta Insert Time'
        )->addColumn(
            'meta_processed',
            Table::TYPE_INTEGER,
            '1',
            ['unsigned' => true, 'nullable' => false, 'default' => 0],
            'Meta Processed'
        )->addForeignKey(
            $installer->getFkName(
                self::FLOW_DOCUMENT_TABLE,
                'meta_file',
                'flow_inboundflow',
                'id'
            ),
            'meta_file',
            $installer->getTable('flow_inboundflow'),
            'id',
            Table::ACTION_CASCADE
        );

        $installer->getConnection()->createTable($documentTable);
    }

    /**
     * @param SchemaSetupInterface $setup
     * @throws Zend_Db_Exception
     */
    public function createBundleTable(SchemaSetupInterface $setup)
    {
        if (!$setup->tableExists('flow_from_bundle')) {
            $table = $setup->getConnection()->newTable(
                $setup->getTable('flow_from_bundle')
            )->addColumn(
                    'meta_id',
                    Table::TYPE_INTEGER,
                    null,
                    ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
                    'flow_from_bundle'
                )->addColumn(
                    'meta_file',
                    Table::TYPE_INTEGER,
                    null,
                    ['unsigned' => true, 'nullable' => false],
                    'meta_file'
                )->addColumn(
                    'bundle_sku',
                    Table::TYPE_TEXT,
                    '255',
                    [],
                    'bundle_sku'
                )->addColumn(
                    'bundle_name',
                    Table::TYPE_TEXT,
                    '255',
                    [],
                    'bundle_name'
                )->addColumn(
                    'simple_sku',
                    Table::TYPE_TEXT,
                    '255',
                    [],
                    'simple_sku'
                )->addColumn(
                    'bundle_option_name',
                    Table::TYPE_TEXT,
                    '255',
                    [],
                    'bundle_option_name'
                )->addColumn(
                    'bundle_type_option',
                    Table::TYPE_TEXT,
                    '255',
                    [],
                    'bundle_type_option'
                )->addColumn(
                    'bundle_option_required',
                    Table::TYPE_TEXT,
                    '255',
                    [],
                    'bundle_option_required'
                )->addColumn(
                    'bundle_option_default',
                    Table::TYPE_TEXT,
                    '255',
                    [],
                    'bundle_option_default'
                )->addColumn(
                    'bundle_option_default_qty',
                    Table::TYPE_TEXT,
                    '255',
                    [],
                    'bundle_option_default_qty'
                )->addColumn(
                    'bundle_option_can_change_qty',
                    Table::TYPE_TEXT,
                    '255',
                    [],
                    'bundle_option_can_change_qty'
                )->addColumn(
                    'bundle_price_view',
                    Table::TYPE_TEXT,
                    '255',
                    [],
                    'bundle_price_view'
                )->addColumn(
                    'bundle_price_type',
                    Table::TYPE_TEXT,
                    '255',
                    [],
                    'bundle_price_type'
                )->addColumn(
                    'meta_processed',
                    Table::TYPE_INTEGER,
                    '1',
                    [],
                    'meta_processed'
                )->addColumn(
                    'meta_insert_time',
                    Table::TYPE_DATETIME,
                    '10',
                    ['unsigned' => true, 'nullable' => false],
                    'meta_insert_time'
                )->addColumn(
                    'meta_process_time',
                    Table::TYPE_DATETIME,
                    '10',
                    [],
                    'meta_process_time'
                )->addIndex(
                    $setup->getIdxName('flow_from_bundle_meta_file', ['meta_file']), ['meta_file']
                )->addForeignKey(
                    $setup->getFkName(
                        'flow_from_bundle',
                        'meta_file',
                        'flow_inboundflow',
                        'id'
                    ),
                    'meta_file',
                    $setup->getTable('flow_inboundflow'),
                    'id',
                    Table::ACTION_CASCADE
                );

            $setup->getConnection()->createTable($table);
        }
    }

    /**
     * @param SchemaSetupInterface $setup
     * @param ModuleContextInterface $context
     * @throws Zend_Db_Exception
     */
    public function createSubscribersTable(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        /**
         * Create table 'flow_from_subscriber' if not exists
         */
        $table_name = 'flow_from_subscriber';
        if (!$setup->tableExists($table_name)) {
            $table = $setup->getConnection()->newTable(
                $setup->getTable($table_name)
            )->addColumn(
                    'email',
                    Table::TYPE_TEXT,
                    '90',
                    [],
                    'email'
                )->addColumn(
                    'store_id',
                    Table::TYPE_SMALLINT,
                    '5',
                    ['unsigned' => true],
                    'store_id'
                )->addColumn(
                    'status',
                    Table::TYPE_INTEGER,
                    '10',
                    [],
                    'subscriber status'
                )->addColumn(
                    'meta_id',
                    Table::TYPE_INTEGER,
                    null,
                    ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
                    'id'
                )->addColumn(
                    'meta_file',
                    Table::TYPE_INTEGER,
                    null,
                    ['unsigned' => true, 'nullable' => false],
                    'meta_file'
                )->addColumn(
                    'meta_ref_id',
                    Table::TYPE_INTEGER,
                    '11',
                    [],
                    'meta_ref_id'
                )->addColumn(
                    'meta_processed',
                    Table::TYPE_INTEGER,
                    '1',
                    ['default' => 0],
                    'meta_processed'
                )->addColumn(
                    'meta_process_time',
                    Table::TYPE_DATETIME,
                    '10',
                    [],
                    'meta_process_time'
                )->addIndex(
                    $setup->getIdxName($table_name, ['email']), ['email']
                )->addIndex(
                    $setup->getIdxName($table_name, ['store_id']), ['store_id']
                )->addIndex(
                    $setup->getIdxName($table_name, ['status']), ['status']
                )->addIndex(
                    $setup->getIdxName($table_name, ['meta_file']), ['meta_file']
                )->addForeignKey(
                    $setup->getFkName(
                        $table_name,
                        'store_id',
                        'store',
                        'store_id'
                    ),
                    'store_id',
                    $setup->getTable('store'),
                    'store_id'
                )->addForeignKey(
                    $setup->getFkName(
                        $table_name,
                        'meta_file',
                        'flow_inboundflow',
                        'id'
                    ),
                    'meta_file',
                    $setup->getTable('flow_inboundflow'),
                    'id',
                    Table::ACTION_CASCADE
                )->setComment(
                    "FiloBlu Flow {$table_name}"
                );

            $setup->getConnection()->createTable($table);
        }
    }

    /**
     * @param SchemaSetupInterface $setup
     * @param ModuleContextInterface $context
     */
    protected function addStockCompensationColumns(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        $table = $setup->getTable('flow_from_stock');
        $setup->getConnection()->addColumn(
            $table, 'final_quantity', [
                'type'     => Table::TYPE_INTEGER,
                'nullable' => true,
                'comment'  => 'Reservation'
            ]
        );
    }

    /**
     * @param SchemaSetupInterface $installer
     * @param ModuleContextInterface $context
     * @throws Zend_Db_Exception
     */
    protected function createSwatchTable(SchemaSetupInterface $installer, ModuleContextInterface $context)
    {
        /**
         * Create table 'flow_swatch' if not exists
         */
        if ($installer->tableExists(self::FLOW_SWATCH_TABLE)) {
            return;
        }

        $swatchTable = $installer->getConnection()->newTable(
            $installer->getTable(self::FLOW_SWATCH_TABLE)
        )->addColumn(
            'id',
            Table::TYPE_INTEGER,
            null,
            ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
            'Swatch Id'
        )->addColumn(
            'name',
            Table::TYPE_TEXT,
            '255',
            ['nullable' => false],
            'Swatch Name'
        )->addColumn(
            'attribute',
            Table::TYPE_TEXT,
            '50',
            [],
            'Swatch attribute'
        )->addColumn(
            'option_name',
            Table::TYPE_TEXT,
            '255',
            [],
            'Swatch Option Name'
        )->addColumn(
            'option_id',
            Table::TYPE_INTEGER,
            null,
            [],
            'Swatch Option Id'
        )->addColumn(
            'type',
            Table::TYPE_TEXT,
            '20',
            [],
            'Swatch Type'
        )->addColumn(
            'path',
            Table::TYPE_TEXT,
            '255',
            [],
            'Swatch Path'
        )->addColumn(
            'status',
            Table::TYPE_TEXT,
            '50',
            [],
            'Swatch Status'
        )->addColumn(
            'log',
            Table::TYPE_TEXT,
            '64k',
            [],
            'Swatch Log'
        )->addColumn(
            'meta_file',
            Table::TYPE_INTEGER,
            null,
            ['unsigned' => true, 'nullable' => false],
            'Inbound Flow file'
        )->addColumn(
            'meta_insert_time',
            Table::TYPE_DATETIME,
            '10',
            ['unsigned' => true, 'nullable' => false],
            'Meta Insert Time'
        )->addColumn(
            'meta_processed',
            Table::TYPE_INTEGER,
            '1',
            ['unsigned' => true, 'nullable' => false, 'default' => 0],
            'Meta Processed'
        )->addForeignKey(
            $installer->getFkName(
                self::FLOW_SWATCH_TABLE,
                'meta_file',
                'flow_inboundflow',
                'id'
            ),
            'meta_file',
            $installer->getTable('flow_inboundflow'),
            'id',
            Table::ACTION_CASCADE
        );

        $installer->getConnection()->createTable($swatchTable);
    }

    /**
     * @param $setup
     * @param $context
     */
    public function addVideosTable($setup, $context)
    {
        /**
         * Create table 'flow_videosflow' if not exists
         */

        if (!$setup->tableExists('flow_videosflow')) {
            $table = $setup->getConnection()->newTable(
                $setup->getTable('flow_videosflow')
            )->addColumn(
                    'id',
                    Table::TYPE_INTEGER,
                    null,
                    ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
                    null
                )->addColumn(
                    'video_name',
                    Table::TYPE_TEXT,
                    '64k',
                    [],
                    null
                )->addColumn(
                    'video_hide',
                    Table::TYPE_TEXT,
                    10,
                    [],
                    null
                )->addColumn(
                    'video_type',
                    Table::TYPE_TEXT,
                    50,
                    [],
                    null
                )->addColumn(
                    'video_alt',
                    Table::TYPE_TEXT,
                    255,
                    [],
                    null
                )->addColumn(
                    'video_path',
                    Table::TYPE_TEXT,
                    null,
                    [],
                    null
                )->addColumn(
                    'video_position',
                    Table::TYPE_TEXT,
                    10,
                    [],
                    null
                )->addColumn(
                    'video_sku',
                    Table::TYPE_TEXT,
                    100,
                    [],
                    null
                )->addColumn(
                    'video_status',
                    Table::TYPE_TEXT,
                    '30',
                    [],
                    null
                )->addColumn(
                    'video_queue_time',
                    Table::TYPE_DATETIME,
                    null,
                    [],
                    null
                )->addColumn(
                    'video_receive_time',
                    Table::TYPE_DATETIME,
                    null,
                    [],
                    null
                )->addColumn(
                    'video_process_time',
                    Table::TYPE_DATETIME,
                    null,
                    [],
                    null
                )->addColumn(
                    'meta_file',
                    Table::TYPE_INTEGER,
                    null,
                    ['nullable' => false],
                    null
                )->addColumn(
                    'meta_processed',
                    Table::TYPE_SMALLINT,
                    '1',
                    ['nullable' => false, 'default' => '0'],
                    null
                )->addColumn(
                    'log',
                    Table::TYPE_TEXT,
                    '64k',
                    [],
                    null
                );

            $setup->getConnection()->createTable($table);
        }
    }

    /**
     * @param $setup
     */
    public function addLookupSkuColumn($setup)
    {
        $table = $setup->getTable('flow_from_stock');
        $setup->getConnection()->addColumn(
            $table, 'lookup_sku', [
                'type'     => Table::TYPE_TEXT,
                'nullable' => true,
                'length'   => 40,
                'comment'  => 'The value will be used to calculate the SKU (ex. this can be a barcode)',
                'after'    => 'sku'
            ]
        );
    }

    /**
     * @param SchemaSetupInterface $setup
     */
    public function addIndexes(SchemaSetupInterface $setup)
    {
        $missingIndex = [
            'flow_from_eavs'   => [
                'e',
                'a',
                's',
                'l',
                'meta_id',
                'meta_ref_id',
                'executed_on',
                'meta_file',
                'meta_processed',
                'meta_insert_time',
                'meta_process_time'
            ],
            'flow_from_stock'  => [
                'sku',
                'lookup_sku',
                'magazzino',
                'fisico_disponibile',
                'meta_id',
                'meta_file',
                'meta_processed',
                'meta_process_time',
                'final_quantity'
            ],
            'flow_from_price'  => [
                'sku',
                'paese',
                'prezzo',
                'valuta',
                'meta_id',
                'meta_ref_id',
                'meta_file',
                'meta_processed',
                'meta_insert_time',
                'meta_process_time'
            ],
            'flow_from_ite'    => [
                'codice_articolo',
                'codice_articolo_del_fornitore',
                'nome_articolo',
                'codice_configurabile',
                'configurable_attributes',
                'configurable_values',
                'fascia_iva_articoli',
                'visibility',
                'attribute_set',
                'meta_id',
                'meta_ref_id',
                'meta_file',
                'meta_processed',
                'meta_insert_time',
                'meta_process_time'
            ],
            'flow_from_bundle' => [
                'meta_id',
                'meta_file',
                'bundle_sku',
                'bundle_name',
                'simple_sku',
                'bundle_option_name',
                'bundle_type_option',
                'bundle_option_required',
                'bundle_option_default',
                'bundle_option_default_qty',
                'bundle_option_can_change_qty',
                'bundle_price_view',
                'bundle_price_type',
                'meta_processed',
                'meta_insert_time',
                'meta_process_time'
            ]
        ];

        foreach ($missingIndex as $tableName => $columns) {
            foreach ($columns as $column) {
                $setup->getConnection()->addIndex(
                    $setup->getTable($tableName),
                    $setup->getIdxName($tableName, [$column]),
                    $column
                );
            }
        }
    }

    /**
     * @param SchemaSetupInterface $setup
     * @param ModuleContextInterface $context
     * @return void
     */
    public function extendsInboundFlow(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        $setup->getConnection()->addColumn(
                $setup->getTable('flow_inboundflow'), 'lines', [
                    'type'     => Table::TYPE_INTEGER,
                    'nullable' => true,
                    'after'    => 'retry',
                    'comment'  => 'Number of processed lines',
                    'unsigned' => true,
                    'default'  => 0
                ]
            );

        $setup->getConnection()->addColumn(
                $setup->getTable('flow_inboundflow'), 'errors', [
                    'type'     => Table::TYPE_INTEGER,
                    'nullable' => true,
                    'after'    => 'lines',
                    'comment'  => 'Number of processed lines',
                    'unsigned' => true,
                    'default'  => 0
                ]
            );

        $setup->getConnection()->addColumn(
                $setup->getTable('flow_inboundflow'), 'last_activity', [
                    'type'     => Table::TYPE_DATETIME,
                    'nullable' => true,
                    'after'    => 'errors',
                    'comment'  => 'Last activity'
                ]
            );

        foreach (['last_activity', 'errors', 'lines'] as $column) {
            $setup->getConnection()->addIndex(
                $setup->getTable('flow_inboundflow'),
                $setup->getIdxName('flow_inboundflow', [$column]),
                $column
            );
        }
    }

    /**
     * @param SchemaSetupInterface $setup
     * @param ModuleContextInterface $context
     * @throws Zend_Db_Exception
     */
    public function createStockAdjustmentTable(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        /**
         * Create table 'flow_from_stock_adjustment' if not exists
         */

        if (!$setup->tableExists(self::FLOW_STOCK_ADJUSTMENT_TABLE)) {
            $table = $setup->getConnection()->newTable(
                $setup->getTable(self::FLOW_STOCK_ADJUSTMENT_TABLE)
            )->addColumn(
                    'sku',
                    Table::TYPE_TEXT,
                    '40',
                    [],
                    'sku'
                )->addColumn(
                    'warehouse',
                    Table::TYPE_TEXT,
                    '30',
                    [],
                    'warehouse'
                )->addColumn(
                    'adjustment',
                    Table::TYPE_INTEGER,
                    '10',
                    [],
                    'adjustment'
                )->addColumn(
                    'final_quantity',
                    Table::TYPE_INTEGER,
                    '10',
                    [],
                    'final quantity'
                )->addColumn(
                    'source',
                    Table::TYPE_TEXT,
                    '30',
                    [],
                    'source'
                )->addColumn(
                    'detail',
                    Table::TYPE_TEXT,
                    '255',
                    [],
                    'detail'
                )->addColumn(
                    'meta_id',
                    Table::TYPE_INTEGER,
                    null,
                    ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
                    'id'
                )->addColumn(
                    'meta_file',
                    Table::TYPE_INTEGER,
                    '11',
                    [],
                    'meta_ref_id'
                )->addColumn(
                    'meta_ref_id',
                    Table::TYPE_INTEGER,
                    '11',
                    [],
                    'meta_ref_id'
                )->addColumn(
                    'meta_processed',
                    Table::TYPE_INTEGER,
                    '1',
                    [],
                    'meta_processed'
                )->addColumn(
                    'meta_insert_time',
                    Table::TYPE_DATETIME,
                    '10',
                    [],
                    'meta_insert_time'
                )->addColumn(
                    'meta_process_time',
                    Table::TYPE_DATETIME,
                    '10',
                    [],
                    'meta_process_time'
                )->setComment(
                    'FiloBlu Flow ' . self::FLOW_STOCK_ADJUSTMENT_TABLE
                );

            $setup->getConnection()->createTable($table);
        }
    }

    /**
     * @param SchemaSetupInterface $setup
     * @param ModuleContextInterface $context
     * @return void
     */
    public function changePaeseSkuLength(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        $setup->getConnection()->modifyColumn(
            $setup->getTable('flow_from_price'), 'paese', [
                'type'    => Table::TYPE_TEXT,
                'length'  => '255',
                'comment' => 'paese'
            ]
        );
        $setup->getConnection()->modifyColumn(
            $setup->getTable('flow_from_price'), 'sku', [
                'type'    => Table::TYPE_TEXT,
                'length'  => '255',
                'comment' => 'sku'
            ]
        );
    }

    /**
     * @param SchemaSetupInterface $setup
     * @param ModuleContextInterface $context
     * @return void
     * @throws Zend_Db_Exception
     */
    public function addGroupedTable(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        if (!$setup->tableExists('flow_from_grouped')) {
            $table = $setup->getConnection()->newTable(
                $setup->getTable('flow_from_grouped')
            )->addColumn(
                    'meta_id',
                    Table::TYPE_INTEGER,
                    null,
                    ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
                    'flow_from_grouped Id'
                )->addColumn(
                    'meta_file',
                    Table::TYPE_INTEGER,
                    null,
                    ['unsigned' => true, 'nullable' => false],
                    'meta_file'
                )->addColumn(
                    'grouped_sku',
                    Table::TYPE_TEXT,
                    '255',
                    [],
                    'Grouped SKU'
                )->addColumn(
                    'grouped_name',
                    Table::TYPE_TEXT,
                    '255',
                    [],
                    'Grouped Name'
                )->addColumn(
                    'child_sku',
                    Table::TYPE_TEXT,
                    '255',
                    [],
                    'child_sku'
                )
                ->addColumn(
                    'quantity',
                    Table::TYPE_INTEGER,
                    null,
                    ['unsigned' => true, 'nullable' => true, 'default' => 1],
                    'Linked quantity'
                )
                ->addColumn(
                    'position',
                    Table::TYPE_INTEGER,
                    null,
                    ['unsigned' => true, 'nullable' => true],
                    'Position'
                )
                ->addColumn(
                    'meta_processed',
                    Table::TYPE_INTEGER,
                    '1',
                    [],
                    'meta_processed'
                )->addColumn(
                    'meta_insert_time',
                    Table::TYPE_DATETIME,
                    '10',
                    ['unsigned' => true, 'nullable' => false],
                    'meta_insert_time'
                )->addColumn(
                    'meta_process_time',
                    Table::TYPE_DATETIME,
                    '10',
                    [],
                    'meta_process_time'
                )->addIndex(
                    $setup->getIdxName('flow_from_grouped_meta_file', ['meta_file']), ['meta_file']
                )->addForeignKey(
                    $setup->getFkName(
                        'flow_from_grouped',
                        'meta_file',
                        'flow_inboundflow',
                        'id'
                    ),
                    'meta_file',
                    $setup->getTable('flow_inboundflow'),
                    'id',
                    Table::ACTION_CASCADE
                );

            $setup->getConnection()->createTable($table);
        }
    }

    public function createSizeguideTable(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        /**
         * Create table 'flow_from_sizeguide' if not exists
         */
        $table_name = 'flow_from_sizeguide';
        if (!$setup->tableExists($table_name)) {
            $table = $setup->getConnection()->newTable(
                $setup->getTable($table_name)
            )->addColumn(
                'row_number',
                Table::TYPE_SMALLINT,
                '3',
                [],
                'data value'
            )->addColumn(
                'row',
                Table::TYPE_TEXT,
                '64k',
                [],
                'data value'
            )->addColumn(
                'meta_id',
                Table::TYPE_INTEGER,
                null,
                ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
                'id'
            )->addColumn(
                'meta_file',
                Table::TYPE_INTEGER,
                null,
                ['unsigned' => true, 'nullable' => false],
                'meta_file'
            )->addColumn(
                'meta_ref_id',
                Table::TYPE_INTEGER,
                '11',
                [],
                'meta_ref_id'
            )->addColumn(
                'meta_processed',
                Table::TYPE_INTEGER,
                '1',
                ['default' => 0],
                'meta_processed'
            )->addColumn(
                'meta_insert_time',
                Table::TYPE_DATETIME,
                '10',
                [],
                'meta_insert_time'
            )->addColumn(
                'meta_process_time',
                Table::TYPE_DATETIME,
                '10',
                [],
                'meta_process_time'
            )->addIndex(
                $setup->getIdxName($table_name, ['meta_file']), ['meta_file']
            )->addForeignKey(
                $setup->getFkName(
                    $table_name,
                    'meta_file',
                    'flow_inboundflow',
                    'id'
                ),
                'meta_file',
                $setup->getTable('flow_inboundflow'),
                'id',
                Table::ACTION_CASCADE
            )->setComment(
                "FiloBlu Flow {$table_name}"
            );

            $setup->getConnection()->createTable($table);
        }
    }

    /**
     * @param SchemaSetupInterface $setup
     * @param ModuleContextInterface $context
     * @return void
     * @throws Zend_Db_Exception
     */
    public function addSharedCatalogTable(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        if (!$setup->tableExists('flow_from_sharedcatalog')) {
            $table = $setup->getConnection()->newTable(
                $setup->getTable('flow_from_sharedcatalog')
            )->addColumn(
                'meta_id',
                Table::TYPE_INTEGER,
                null,
                ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
                'flow_from_sharedcatalog Id'
            )->addColumn(
                'meta_file',
                Table::TYPE_INTEGER,
                null,
                ['unsigned' => true, 'nullable' => false],
                'meta_file'
            )->addColumn(
                'name',
                Table::TYPE_TEXT,
                '255',
                [],
                'SharedCatalog Name'
            )->addColumn(
                'description',
                Table::TYPE_TEXT,
                '1024',
                [],
                'Store Code'
            )->addColumn(
                'store_code',
                Table::TYPE_TEXT,
                '25',
                [],
                'Store Code'
            )->addColumn(
                'tax_class',
                Table::TYPE_TEXT,
                '100',
                [],
                'Customer Tax Class'
            )->addColumn(
                'meta_processed',
                Table::TYPE_INTEGER,
                '1',
                [],
                'meta_processed'
            )->addColumn(
                'meta_insert_time',
                Table::TYPE_DATETIME,
                '10',
                ['unsigned' => true, 'nullable' => false],
                'meta_insert_time'
            )->addColumn(
                'meta_process_time',
                Table::TYPE_DATETIME,
                '10',
                [],
                'meta_process_time'
            )->addIndex(
                $setup->getIdxName('flow_from_sharedcatalog_meta_file', ['meta_file']), ['meta_file']
            )->addForeignKey(
                $setup->getFkName(
                    'flow_from_sharedcatalog',
                    'meta_file',
                    'flow_inboundflow',
                    'id'
                ),
                'meta_file',
                $setup->getTable('flow_inboundflow'),
                'id',
                Table::ACTION_CASCADE
            );

            $setup->getConnection()->createTable($table);
        }
    }

    /**
     * @param SchemaSetupInterface $setup
     * @param ModuleContextInterface $context
     * @return void
     * @throws Zend_Db_Exception
     */
    public function addSharedCatalogPricesTable(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        if (!$setup->tableExists('flow_from_sharedcatalog_prices')) {
            $table = $setup->getConnection()->newTable(
                $setup->getTable('flow_from_sharedcatalog_prices')
            )->addColumn(
                'meta_id',
                Table::TYPE_INTEGER,
                null,
                ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
                'flow_from_sharedcatalog_prices Id'
            )->addColumn(
                'meta_file',
                Table::TYPE_INTEGER,
                null,
                ['unsigned' => true, 'nullable' => false],
                'meta_file'
            )->addColumn(
                'sharedcatalog',
                Table::TYPE_TEXT,
                '255',
                [],
                'SharedCatalog'
            )->addColumn(
                'sku',
                Table::TYPE_TEXT,
                '40',
                [],
                'sku'
            )->addColumn(
                'price',
                Table::TYPE_DECIMAL,
                '12,4',
                ['nullable' => false, 'default' => '0.0000'],
                'Price'
            )->addColumn(
                'price_type',
                Table::TYPE_TEXT,
                '40',
                [],
                'price_type'
            )->addColumn(
                'quantity',
                Table::TYPE_INTEGER,
                '10',
                [],
                'Quantity'
            )->addColumn(
                'tax_class',
                Table::TYPE_TEXT,
                '100',
                [],
                'Product Tax Class'
            )->addColumn(
                'meta_processed',
                Table::TYPE_INTEGER,
                '1',
                [],
                'meta_processed'
            )->addColumn(
                'meta_insert_time',
                Table::TYPE_DATETIME,
                '10',
                ['unsigned' => true, 'nullable' => false],
                'meta_insert_time'
            )->addColumn(
                'meta_process_time',
                Table::TYPE_DATETIME,
                '10',
                [],
                'meta_process_time'
            )->addIndex(
                $setup->getIdxName('flow_from_sharedcatalog_prices_meta_file', ['meta_file']), ['meta_file']
            )->addForeignKey(
                $setup->getFkName(
                    'flow_from_sharedcatalog_prices',
                    'meta_file',
                    'flow_inboundflow',
                    'id'
                ),
                'meta_file',
                $setup->getTable('flow_inboundflow'),
                'id',
                Table::ACTION_CASCADE
            );

            $setup->getConnection()->createTable($table);
        }
    }

    /**
     * @param SchemaSetupInterface $setup
     * @param ModuleContextInterface $context
     * @return void
     * @throws Zend_Db_Exception
     */
    public function addEavsGroupedTable(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        if (!$setup->tableExists('flow_from_eavs_grouped')) {
            $table = $setup->getConnection()->newTable(
                $setup->getTable('flow_from_eavs_grouped')
            )->addColumn(
                'e',
                Table::TYPE_TEXT,
                '255',
                [],
                'e'
            )->addColumn(
                'a',
                Table::TYPE_TEXT,
                '255',
                [],
                'a'
            )->addColumn(
                'v',
                Table::TYPE_TEXT,
                '65535',
                [],
                'v'
            )->addColumn(
                's',
                Table::TYPE_TEXT,
                '255',
                [],
                's'
            )->addColumn(
                'meta_id',
                Table::TYPE_INTEGER,
                null,
                ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
                'flow_channels'
            )->addColumn(
                'meta_ref_id',
                Table::TYPE_INTEGER,
                '11',
                [],
                'meta_ref_id'
            )->addColumn(
                'executed_on',
                Table::TYPE_TEXT,
                '25',
                ['nullable' => true],
                'executed_on'
            )->addColumn(
                'meta_file',
                Table::TYPE_INTEGER,
                null,
                [],
                'meta_file'
            )->addColumn(
                'meta_processed',
                Table::TYPE_INTEGER,
                '1',
                [],
                'meta_processed'
            )->addColumn(
                'meta_insert_time',
                Table::TYPE_DATETIME,
                '10',
                ['unsigned' => true, 'nullable' => false],
                'meta_insert_time'
            )->addColumn(
                'meta_process_time',
                Table::TYPE_DATETIME,
                '10',
                [],
                'meta_process_time'
            );

            $setup->getConnection()->createTable($table);
        }
    }

    public function updateBundleTable(SchemaSetupInterface $setup)
    {
        if ($setup->tableExists('flow_from_bundle')) {
            $setup->getConnection()
            ->addColumn(
                $setup->getTable('flow_from_bundle'), 'bundle_group_position', [
                    'type'     => Table::TYPE_INTEGER,
                    'nullable' => false,
                    'comment'  => 'bundle_group_position',
                    'after'    => 'simple_sku'
                ]
            );

            $setup->getConnection()
            ->addColumn(
                $setup->getTable('flow_from_bundle'), 'bundle_option_position', [
                    'type'     => Table::TYPE_INTEGER,
                    'nullable' => false,
                    'comment'  => 'bundle_option_position',
                    'after'    => 'bundle_type_option'
                ]
            );
        }
    }

    public function addSwatchColorsTable(SchemaSetupInterface $setup)
    {

        $tableName = $setup->getTable('flow_swatch_color');

        if (!$setup->getConnection()->isTableExists($tableName)) {
            $table = $setup->getConnection()->newTable($tableName)
                ->addColumn(
                    'attribute',
                    Table::TYPE_TEXT,
                    255,
                    ['nullable' => false],
                    'Atrribute Code'
                )
                ->addColumn(
                    'option_name',
                    Table::TYPE_TEXT,
                    255,
                    ['nullable' => false],
                    'Swatch Option Name'
                )->addColumn(
                    'option_id',
                    Table::TYPE_INTEGER,
                    null,
                    [],
                    'Swatch Option Id'
                )->addColumn(
                    'value',
                    Table::TYPE_TEXT,
                    255,
                    ['nullable' => false],
                    'Attribute Value'
                )->addColumn(
                    'type',
                    Table::TYPE_TEXT,
                    '20',
                    [],
                    'Swatch Type'
                )->addColumn(
                    'meta_id',
                    Table::TYPE_INTEGER,
                    null,
                    ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
                    'Meta ID'
                )
                ->addColumn(
                    'meta_ref_id',
                    Table::TYPE_INTEGER,
                    null,
                    ['unsigned' => true, 'nullable' => true],
                    'Meta Ref ID'
                )
                ->addColumn(
                    'meta_file',
                    Table::TYPE_TEXT,
                    255,
                    ['nullable' => true],
                    'Meta File'
                )
                ->addColumn(
                    'meta_processed',
                    Table::TYPE_SMALLINT,
                    null,
                    ['nullable' => true, 'default' => 0],
                    'Meta Processed'
                )
                ->addColumn(
                    'meta_insert_time',
                    Table::TYPE_TIMESTAMP,
                    null,
                    ['nullable' => true, 'default' => Table::TIMESTAMP_INIT],
                    'Meta Insert Time'
                )
                ->addColumn(
                    'meta_process_time',
                    Table::TYPE_TIMESTAMP,
                    null,
                    ['nullable' => true, 'default' => Table::TIMESTAMP_INIT_UPDATE],
                    'Meta Process Time'
                )
                ->setComment('FiloBlu Swatch Color');

            $setup->getConnection()->createTable($table);
        }
    }

    /**
     * @param SchemaSetupInterface $setup
     * @return void
     */
     public function fixReceivingTimeColumn(SchemaSetupInterface $setup)
     {
         if ($setup->tableExists('flow_inboundflow')) {
             $setup->getConnection()->modifyColumn(
                 $setup->getTable('flow_inboundflow'),
                 'receiving_time',
                 [
                     'type'    => Table::TYPE_TIMESTAMP,
                     'nullable' => false,
                     'default' => Table::TIMESTAMP_INIT_UPDATE,
                     'comment' => 'receiving_time'
                 ]
             );
         }
     }

    /**
     * @param SchemaSetupInterface $setup
     * @param ModuleContextInterface $context
     * @return void
     * @throws Zend_Db_Exception
     */
    public function createFlowFromCustomerTable(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        if (!$setup->tableExists('flow_from_customer')) {
            $table = $setup->getConnection()->newTable(
                $setup->getTable('flow_from_customer')
            )->addColumn(
                'e',
                Table::TYPE_TEXT,
                '255',
                ['nullable' => true],
                'e'
            )->addColumn(
                'a',
                Table::TYPE_TEXT,
                '255',
                ['nullable' => true],
                'a'
            )->addColumn(
                'v',
                Table::TYPE_TEXT,
                null,
                [],
                'v'
            )->addColumn(
                's',
                Table::TYPE_TEXT,
                '255',
                ['nullable' => true],
                's'
            )->addColumn(
                'l',
                Table::TYPE_TEXT,
                '20',
                ['nullable' => true],
                'l'
            )->addColumn(
                'meta_id',
                Table::TYPE_INTEGER,
                null,
                ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
                'flow_channels'
            )->addColumn(
                'meta_ref_id',
                Table::TYPE_INTEGER,
                null,
                ['nullable' => true],
                'meta_ref_id'
            )->addColumn(
                'executed_on',
                Table::TYPE_TEXT,
                '25',
                ['nullable' => true],
                'executed_on'
            )->addColumn(
                'meta_file',
                Table::TYPE_INTEGER,
                null,
                ['nullable' => true],
                'meta_file'
            )->addColumn(
                'meta_processed',
                Table::TYPE_INTEGER,
                null,
                ['nullable' => true],
                'meta_processed'
            )->addColumn(
                'meta_insert_time',
                Table::TYPE_DATETIME,
                null,
                ['nullable' => false],
                'meta_insert_time'
            )->addColumn(
                'meta_process_time',
                Table::TYPE_DATETIME,
                null,
                ['nullable' => true],
                'meta_process_time'
            )->addColumn(
                'params',
                Table::TYPE_TEXT,
                null,
                [],
                'params'
            )->addColumn(
                'status',
                Table::TYPE_TEXT,
                '255',
                ['nullable' => true],
                'status'
            )->addIndex(
                $setup->getIdxName('flow_from_customer', ['e']),
                ['e']
            )->addIndex(
                $setup->getIdxName('flow_from_customer', ['a']),
                ['a']
            )->addIndex(
                $setup->getIdxName('flow_from_customer', ['s']),
                ['s']
            )->addIndex(
                $setup->getIdxName('flow_from_customer', ['l']),
                ['l']
            )->addIndex(
                $setup->getIdxName('flow_from_customer', ['meta_id']),
                ['meta_id']
            )->addIndex(
                $setup->getIdxName('flow_from_customer', ['meta_ref_id']),
                ['meta_ref_id']
            )->addIndex(
                $setup->getIdxName('flow_from_customer', ['executed_on']),
                ['executed_on']
            )->addIndex(
                $setup->getIdxName('flow_from_customer', ['meta_file']),
                ['meta_file']
            )->addIndex(
                $setup->getIdxName('flow_from_customer', ['meta_processed']),
                ['meta_processed']
            )->addIndex(
                $setup->getIdxName('flow_from_customer', ['meta_insert_time']),
                ['meta_insert_time']
            )->addIndex(
                $setup->getIdxName('flow_from_customer', ['meta_process_time']),
                ['meta_process_time']
            )->setComment(
                'flow_from_customer'
            );

            $setup->getConnection()->createTable($table);
        }
    }
}
