/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import templateUrl from './template.tpl.pug';
import './style.scss';
import _ from 'lodash';
import naturalCompare from 'natural-compare-lite';
import find from 'lodash/fp/find';
import get from 'lodash/fp/get';
import {combineLatest, EMPTY, from, merge, of, race, timer} from 'rxjs';
import {distinctUntilChanged, filter, map, pluck, switchMap, take, tap} from 'rxjs/operators';
import ObjectID from 'bson-objectid';
import {uniqueName} from 'app/utils/uniqueName';
import {defaultNames} from '../../defaultNames';
// eslint-disable-next-line
import {UIRouter} from '@uirouter/angularjs'
import {default as IgniteConfirmBatch} from 'app/services/ConfirmBatch.service';
import {default as ConfigSelectors} from '../../store/selectors';
import {default as ConfigEffects} from '../../store/effects';
import {default as ConfigureState} from '../../services/ConfigureState';
// eslint-disable-next-line
import {default as AgentManager} from 'app/modules/agent/AgentModal.service'
import {default as SqlTypes} from 'app/services/SqlTypes.service';
import {default as JavaTypes} from 'app/services/JavaTypes.service';
// eslint-disable-next-line
import {default as ActivitiesData} from 'app/core/activities/Activities.data';

function _mapCaches(caches = []) {
    return caches.map((cache) => {
        return {label: cache.name, value: cache._id, cache};
    });
}

const INFO_CONNECT_TO_DB = 'Configure connection to database';
const INFO_SELECT_SCHEMAS = 'Select schemas to load tables from';
const INFO_SELECT_TABLES = 'Select tables to import as domain model';
const INFO_SELECT_OPTIONS = 'Select import domain model options';
const LOADING_JDBC_DRIVERS = {text: 'Loading JDBC drivers...'};
const LOADING_SCHEMAS = {text: 'Loading schemas...'};
const LOADING_TABLES = {text: 'Loading tables...'};
const SAVING_DOMAINS = {text: 'Saving domain model...'};

const IMPORT_DM_NEW_CACHE = 1;
const IMPORT_DM_ASSOCIATE_CACHE = 2;

const DFLT_PARTITIONED_CACHE = {
    label: 'PARTITIONED',
    value: -1,
    cache: {
        name: 'PARTITIONED',
        cacheMode: 'PARTITIONED',
        atomicityMode: 'ATOMIC',
        readThrough: true,
        writeThrough: true
    }
};

const DFLT_REPLICATED_CACHE = {
    label: 'REPLICATED',
    value: -2,
    cache: {
        name: 'REPLICATED',
        cacheMode: 'REPLICATED',
        atomicityMode: 'ATOMIC',
        readThrough: true,
        writeThrough: true
    }
};

const CACHE_TEMPLATES = [DFLT_PARTITIONED_CACHE, DFLT_REPLICATED_CACHE];

export class ModalImportModels {
    /**
     * Cluster ID to import models into
     * @type {string}
     */
    clusterID;

    /** @type {ng.ICompiledExpression} */
    onHide;

    static $inject = ['$uiRouter', 'ConfigSelectors', 'ConfigEffects', 'ConfigureState', 'IgniteConfirm', 'IgniteConfirmBatch', 'IgniteFocus', 'SqlTypes', 'JavaTypes', 'IgniteMessages', '$scope', '$rootScope', 'AgentManager', 'IgniteActivitiesData', 'IgniteLoading', 'IgniteFormUtils', 'IgniteLegacyUtils'];

    /**
     * @param {UIRouter} $uiRouter
     * @param {ConfigSelectors} ConfigSelectors
     * @param {ConfigEffects} ConfigEffects
     * @param {ConfigureState} ConfigureState
     * @param {IgniteConfirmBatch} ConfirmBatch
     * @param {SqlTypes} SqlTypes
     * @param {JavaTypes} JavaTypes
     * @param {ng.IScope} $scope
     * @param {ng.IRootScopeService} $root
     * @param {AgentManager} agentMgr
     * @param {ActivitiesData} ActivitiesData
     */
    constructor($uiRouter, ConfigSelectors, ConfigEffects, ConfigureState, Confirm, ConfirmBatch, Focus, SqlTypes, JavaTypes, Messages, $scope, $root, agentMgr, ActivitiesData, Loading, FormUtils, LegacyUtils) {
        this.$uiRouter = $uiRouter;
        this.ConfirmBatch = ConfirmBatch;
        this.ConfigSelectors = ConfigSelectors;
        this.ConfigEffects = ConfigEffects;
        this.ConfigureState = ConfigureState;
        this.$root = $root;
        this.$scope = $scope;
        this.agentMgr = agentMgr;
        this.JavaTypes = JavaTypes;
        this.SqlTypes = SqlTypes;
        this.ActivitiesData = ActivitiesData;
        Object.assign(this, {Confirm, Focus, Messages, Loading, FormUtils, LegacyUtils});
    }

    loadData() {
        return of(this.clusterID).pipe(
            switchMap((id = 'new') => {
                return this.ConfigureState.state$.pipe(this.ConfigSelectors.selectClusterToEdit(id, defaultNames.importedCluster));
            }),
            switchMap((cluster) => {
                return (!(cluster.caches || []).length && !(cluster.models || []).length)
                    ? of({
                        cluster,
                        caches: [],
                        models: []
                    })
                    : from(Promise.all([
                        this.ConfigEffects.etp('LOAD_SHORT_CACHES', {ids: cluster.caches || [], clusterID: cluster._id}),
                        this.ConfigEffects.etp('LOAD_SHORT_MODELS', {ids: cluster.models || [], clusterID: cluster._id})
                    ])).pipe(switchMap(() => {
                        return combineLatest(
                            this.ConfigureState.state$.pipe(this.ConfigSelectors.selectShortCachesValue()),
                            this.ConfigureState.state$.pipe(this.ConfigSelectors.selectShortModelsValue()),
                            (caches, models) => ({
                                cluster,
                                caches,
                                models
                            })
                        ).pipe(take(1));
                    }));
            }),
            take(1)
        );
    }

    saveBatch(batch) {
        if (!batch.length)
            return;

        this.$scope.importDomain.loadingOptions = SAVING_DOMAINS;
        this.Loading.start('importDomainFromDb');

        this.ConfigureState.dispatchAction({
            type: 'ADVANCED_SAVE_COMPLETE_CONFIGURATION',
            changedItems: this.batchActionsToRequestBody(batch),
            prevActions: []
        });

        this.saveSubscription = race(
            this.ConfigureState.actions$.pipe(
                filter((a) => a.type === 'ADVANCED_SAVE_COMPLETE_CONFIGURATION_OK'),
                tap(() => this.onHide())
            ),
            this.ConfigureState.actions$.pipe(
                filter((a) => a.type === 'ADVANCED_SAVE_COMPLETE_CONFIGURATION_ERR')
            )
        ).pipe(
            take(1),
            tap(() => {
                this.Loading.finish('importDomainFromDb');
            })
        )
        .subscribe();
    }

    batchActionsToRequestBody(batch) {
        const result = batch.reduce((req, action) => {
            return {
                ...req,
                cluster: {
                    ...req.cluster,
                    models: [...req.cluster.models, action.newDomainModel._id],
                    caches: [...req.cluster.caches, ...action.newDomainModel.caches]
                },
                models: [...req.models, action.newDomainModel],
                caches: action.newCache
                    ? [...req.caches, action.newCache]
                    : action.cacheStoreChanges
                        ? [...req.caches, {
                            ...this.loadedCaches[action.cacheStoreChanges[0].cacheId],
                            ...action.cacheStoreChanges[0].change
                        }]
                        : req.caches
            };
        }, {cluster: this.cluster, models: [], caches: [], igfss: []});
        result.cluster.models = [...new Set(result.cluster.models)];
        result.cluster.caches = [...new Set(result.cluster.caches)];
        return result;
    }

    onTableSelectionChange(selected) {
        this.$scope.$applyAsync(() => {
            this.$scope.importDomain.tablesToUse = selected;
            this.selectedTablesIDs = selected.map((t) => t.id);
        });
    }

    onSchemaSelectionChange(selected) {
        this.$scope.$applyAsync(() => {
            this.$scope.importDomain.schemasToUse = selected;
            this.selectedSchemasIDs = selected.map((i) => i.name);
        });
    }

    onVisibleRowsChange(rows) {
        return this.visibleTables = rows.map((r) => r.entity);
    }

    onCacheSelect(cacheID) {
        if (cacheID < 0)
            return;

        if (this.loadedCaches[cacheID])
            return;

        return this.onCacheSelectSubcription = merge(
            timer(0, 1).pipe(
                take(1),
                tap(() => this.ConfigureState.dispatchAction({type: 'LOAD_CACHE', cacheID}))
            ),
            race(
                this.ConfigureState.actions$.pipe(
                    filter((a) => a.type === 'LOAD_CACHE_OK' && a.cache._id === cacheID),
                    pluck('cache'),
                    tap((cache) => {
                        this.loadedCaches[cacheID] = cache;
                    })
                ),
                this.ConfigureState.actions$.pipe(
                    filter((a) => a.type === 'LOAD_CACHE_ERR' && a.action.cacheID === cacheID)
                )
            ).pipe(take(1))
        )
        .subscribe();
    }

    $onDestroy() {
        this.subscribers$.unsubscribe();
        if (this.onCacheSelectSubcription) this.onCacheSelectSubcription.unsubscribe();
        if (this.saveSubscription) this.saveSubscription.unsubscribe();
    }

    $onInit() {
        // Restores old behavior
        const {Confirm, ConfirmBatch, Focus, SqlTypes, JavaTypes, Messages, $scope, $root, agentMgr, ActivitiesData, Loading, FormUtils, LegacyUtils} = this;

        /**
         * Convert some name to valid java package name.
         *
         * @param name to convert.
         * @returns {string} Valid java package name.
         */
        const _toJavaPackage = (name) => {
            return name ? name.replace(/[^A-Za-z_0-9/.]+/g, '_') : 'org';
        };

        const importDomainModal = {
            hide: () => {
                agentMgr.stopWatch();
                this.onHide();
            }
        };

        const _makeDefaultPackageName = (user) => user
            ? _toJavaPackage(`${user.email.replace('@', '.').split('.').reverse().join('.')}.model`)
            : void 0;

        this.$scope.ui = {
            generatePojo: true,
            builtinKeys: true,
            generateKeyFields: true,
            usePrimitives: true,
            generateTypeAliases: true,
            generateFieldAliases: true,
            packageNameUserInput: _makeDefaultPackageName($root.user)
        };
        this.$scope.$hide = importDomainModal.hide;

        this.$scope.importCommon = {};

        this.subscription = this.loadData().pipe(tap((data) => {
            this.$scope.caches = _mapCaches(data.caches);
            this.$scope.domains = data.models;
            this.caches = data.caches;
            this.cluster = data.cluster;

            if (!_.isEmpty(this.$scope.caches)) {
                this.$scope.importActions.push({
                    label: 'Associate with existing cache',
                    shortLabel: 'Associate',
                    value: IMPORT_DM_ASSOCIATE_CACHE
                });
            }
            this.$scope.$watch('importCommon.action', this._fillCommonCachesOrTemplates(this.$scope.importCommon), true);
            this.$scope.importCommon.action = IMPORT_DM_NEW_CACHE;
        }));

        // New
        this.loadedCaches = {
            ...CACHE_TEMPLATES.reduce((a, c) => ({...a, [c.value]: c.cache}), {})
        };

        this.actions = [
            {value: 'connect', label: this.$root.IgniteDemoMode ? 'Description' : 'Connection'},
            {value: 'schemas', label: 'Schemas'},
            {value: 'tables', label: 'Tables'},
            {value: 'options', label: 'Options'}
        ];

        // Legacy
        $scope.ui.invalidKeyFieldsTooltip = 'Found key types without configured key fields<br/>' +
            'It may be a result of import tables from database without primary keys<br/>' +
            'Key field for such key types should be configured manually';

        $scope.indexType = LegacyUtils.mkOptions(['SORTED', 'FULLTEXT', 'GEOSPATIAL']);

        $scope.importActions = [{
            label: 'Create new cache by template',
            shortLabel: 'Create',
            value: IMPORT_DM_NEW_CACHE
        }];


        const _dbPresets = [
            {
                db: 'Oracle',
                jdbcDriverClass: 'oracle.jdbc.OracleDriver',
                jdbcUrl: 'jdbc:oracle:thin:@[host]:[port]:[database]',
                user: 'system'
            },
            {
                db: 'DB2',
                jdbcDriverClass: 'com.ibm.db2.jcc.DB2Driver',
                jdbcUrl: 'jdbc:db2://[host]:[port]/[database]',
                user: 'db2admin'
            },
            {
                db: 'SQLServer',
                jdbcDriverClass: 'com.microsoft.sqlserver.jdbc.SQLServerDriver',
                jdbcUrl: 'jdbc:sqlserver://[host]:[port][;databaseName=database]'
            },
            {
                db: 'PostgreSQL',
                jdbcDriverClass: 'org.postgresql.Driver',
                jdbcUrl: 'jdbc:postgresql://[host]:[port]/[database]',
                user: 'sa'
            },
            {
                db: 'MySQL',
                jdbcDriverClass: 'com.mysql.jdbc.Driver',
                jdbcUrl: 'jdbc:mysql://[host]:[port]/[database]',
                user: 'root'
            },
            {
                db: 'MySQL',
                jdbcDriverClass: 'com.mysql.cj.jdbc.Driver',
                jdbcUrl: 'jdbc:mysql://[host]:[port]/[database]',
                user: 'root'
            },
            {
                db: 'MySQL',
                jdbcDriverClass: 'org.mariadb.jdbc.Driver',
                jdbcUrl: 'jdbc:mariadb://[host]:[port]/[database]',
                user: 'root'
            },
            {
                db: 'H2',
                jdbcDriverClass: 'org.h2.Driver',
                jdbcUrl: 'jdbc:h2:tcp://[host]/[database]',
                user: 'sa'
            }
        ];

        $scope.selectedPreset = {
            db: 'Generic',
            jdbcDriverJar: '',
            jdbcDriverClass: '',
            jdbcUrl: 'jdbc:[database]',
            user: 'sa',
            password: '',
            tablesOnly: true
        };

        $scope.demoConnection = {
            db: 'H2',
            jdbcDriverClass: 'org.h2.Driver',
            jdbcUrl: 'jdbc:h2:mem:demo-db',
            user: 'sa',
            password: '',
            tablesOnly: true
        };

        function _loadPresets() {
            try {
                const restoredPresets = JSON.parse(localStorage.dbPresets);

                _.forEach(restoredPresets, (restoredPreset) => {
                    const preset = _.find(_dbPresets, {jdbcDriverClass: restoredPreset.jdbcDriverClass});

                    if (preset) {
                        preset.jdbcUrl = restoredPreset.jdbcUrl;
                        preset.user = restoredPreset.user;
                    }
                });
            }
            catch (ignore) {
                // No-op.
            }
        }

        _loadPresets();

        function _savePreset(preset) {
            try {
                const oldPreset = _.find(_dbPresets, {jdbcDriverClass: preset.jdbcDriverClass});

                if (oldPreset)
                    _.assign(oldPreset, preset);
                else
                    _dbPresets.push(preset);

                localStorage.dbPresets = JSON.stringify(_dbPresets);
            }
            catch (err) {
                Messages.showError(err);
            }
        }

        function _findPreset(selectedJdbcJar) {
            let result = _.find(_dbPresets, function(preset) {
                return preset.jdbcDriverClass === selectedJdbcJar.jdbcDriverClass;
            });

            if (!result)
                result = {db: 'Generic', jdbcUrl: 'jdbc:[database]', user: 'admin'};

            result.jdbcDriverJar = selectedJdbcJar.jdbcDriverJar;
            result.jdbcDriverClass = selectedJdbcJar.jdbcDriverClass;
            result.jdbcDriverImplementationVersion = selectedJdbcJar.jdbcDriverImplementationVersion;

            return result;
        }

        function isValidJavaIdentifier(s) {
            return JavaTypes.validIdentifier(s) && !JavaTypes.isKeyword(s) && JavaTypes.nonBuiltInClass(s) &&
                SqlTypes.validIdentifier(s) && !SqlTypes.isKeyword(s);
        }

        function toJavaIdentifier(name) {
            if (_.isEmpty(name))
                return 'DB';

            const len = name.length;

            let ident = '';

            let capitalizeNext = true;

            for (let i = 0; i < len; i++) {
                const ch = name.charAt(i);

                if (ch === ' ' || ch === '_')
                    capitalizeNext = true;
                else if (ch === '-') {
                    ident += '_';
                    capitalizeNext = true;
                }
                else if (capitalizeNext) {
                    ident += ch.toLocaleUpperCase();

                    capitalizeNext = false;
                }
                else
                    ident += ch.toLocaleLowerCase();
            }

            return ident;
        }

        function toJavaClassName(name) {
            const clazzName = toJavaIdentifier(name);

            if (isValidJavaIdentifier(clazzName))
                return clazzName;

            return 'Class' + clazzName;
        }

        function toJavaFieldName(dbName) {
            const javaName = toJavaIdentifier(dbName);

            const fieldName = javaName.charAt(0).toLocaleLowerCase() + javaName.slice(1);

            if (isValidJavaIdentifier(fieldName))
                return fieldName;

            return 'field' + javaName;
        }

        /**
         * Load list of database schemas.
         */
        const _loadSchemas = () => {
            agentMgr.awaitAgent()
                .then(function() {
                    $scope.importDomain.loadingOptions = LOADING_SCHEMAS;
                    Loading.start('importDomainFromDb');

                    if ($root.IgniteDemoMode)
                        return agentMgr.schemas($scope.demoConnection);

                    const preset = $scope.selectedPreset;

                    _savePreset(preset);

                    return agentMgr.schemas(preset);
                })
                .then((schemaInfo) => {
                    $scope.importDomain.action = 'schemas';
                    $scope.importDomain.info = INFO_SELECT_SCHEMAS;
                    $scope.importDomain.catalog = toJavaIdentifier(schemaInfo.catalog);
                    $scope.importDomain.schemas = _.map(schemaInfo.schemas, (schema) => ({name: schema}));
                    $scope.importDomain.schemasToUse = $scope.importDomain.schemas;
                    this.selectedSchemasIDs = $scope.importDomain.schemas.map((s) => s.name);

                    if ($scope.importDomain.schemas.length === 0)
                        $scope.importDomainNext();
                })
                .catch(Messages.showError)
                .then(() => Loading.finish('importDomainFromDb'));
        };


        this._importCachesOrTemplates = [];

        $scope.tableActionView = (tbl) => {
            const cacheName = get('label')(find({value: tbl.cacheOrTemplate}));

            if (tbl.action === IMPORT_DM_NEW_CACHE)
                return 'Create ' + tbl.generatedCacheName + ' (' + cacheName + ')';

            return 'Associate with ' + cacheName;
        };

        /**
         * Load list of database tables.
         */
        const _loadTables = () => {
            agentMgr.awaitAgent()
                .then(() => {
                    $scope.importDomain.loadingOptions = LOADING_TABLES;
                    Loading.start('importDomainFromDb');

                    $scope.importDomain.allTablesSelected = false;
                    this.selectedTables = [];

                    const preset = $scope.importDomain.demo ? $scope.demoConnection : $scope.selectedPreset;

                    preset.schemas = $scope.importDomain.schemasToUse.map((s) => s.name);

                    return agentMgr.tables(preset);
                })
                .then((tables) => {
                    this._importCachesOrTemplates = CACHE_TEMPLATES.concat($scope.caches);

                    this._fillCommonCachesOrTemplates($scope.importCommon)($scope.importCommon.action);

                    _.forEach(tables, (tbl, idx) => {
                        tbl.id = idx;
                        tbl.action = IMPORT_DM_NEW_CACHE;
                        // tbl.generatedCacheName = toJavaClassName(tbl.table) + 'Cache';
                        tbl.generatedCacheName = uniqueName(toJavaClassName(tbl.table) + 'Cache', this.caches);
                        tbl.cacheOrTemplate = DFLT_PARTITIONED_CACHE.value;
                        tbl.label = tbl.schema + '.' + tbl.table;
                        tbl.edit = false;
                    });

                    $scope.importDomain.action = 'tables';
                    $scope.importDomain.tables = tables;
                    const tablesToUse = tables.filter((t) => LegacyUtils.isDefined(_.find(t.columns, (col) => col.key)));
                    this.selectedTablesIDs = tablesToUse.map((t) => t.id);
                    this.$scope.importDomain.tablesToUse = tablesToUse;

                    $scope.importDomain.info = INFO_SELECT_TABLES;
                })
                .catch(Messages.showError)
                .then(() => Loading.finish('importDomainFromDb'));
        };

        $scope.applyDefaults = () => {
            _.forEach(this.visibleTables, (table) => {
                table.edit = false;
                table.action = $scope.importCommon.action;
                table.cacheOrTemplate = $scope.importCommon.cacheOrTemplate;
            });
        };

        $scope._curDbTable = null;

        $scope.startEditDbTableCache = (tbl) => {
            if ($scope._curDbTable) {
                $scope._curDbTable.edit = false;

                if ($scope._curDbTable.actionWatch) {
                    $scope._curDbTable.actionWatch();
                    $scope._curDbTable.actionWatch = null;
                }
            }

            $scope._curDbTable = tbl;

            const _fillFn = this._fillCommonCachesOrTemplates($scope._curDbTable);

            _fillFn($scope._curDbTable.action);

            $scope._curDbTable.actionWatch = $scope.$watch('_curDbTable.action', _fillFn, true);

            $scope._curDbTable.edit = true;
        };

        /**
         * Show page with import domain models options.
         */
        function _selectOptions() {
            $scope.importDomain.action = 'options';
            $scope.importDomain.button = 'Save';
            $scope.importDomain.info = INFO_SELECT_OPTIONS;

            Focus.move('domainPackageName');
        }

        const _saveDomainModel = (optionsForm) => {
            if (optionsForm.$invalid)
                return this.FormUtils.triggerValidation(optionsForm, this.$scope);

            const generatePojo = $scope.ui.generatePojo;
            const packageName = $scope.ui.packageName;

            const batch = [];
            const checkedCaches = [];

            let containKey = true;
            let containDup = false;

            function dbField(name, jdbcType, nullable, unsigned) {
                const javaTypes = (unsigned && jdbcType.unsigned) ? jdbcType.unsigned : jdbcType.signed;
                const javaFieldType = (!nullable && javaTypes.primitiveType && $scope.ui.usePrimitives) ? javaTypes.primitiveType : javaTypes.javaType;

                return {
                    databaseFieldName: name,
                    databaseFieldType: jdbcType.dbName,
                    javaType: javaTypes.javaType,
                    javaFieldName: toJavaFieldName(name),
                    javaFieldType
                };
            }

            _.forEach($scope.importDomain.tablesToUse, (table, curIx, tablesToUse) => {
                const qryFields = [];
                const indexes = [];
                const keyFields = [];
                const valFields = [];
                const aliases = [];

                const tableName = table.table;
                let typeName = toJavaClassName(tableName);

                if (_.find($scope.importDomain.tablesToUse,
                        (tbl, ix) => ix !== curIx && tableName === tbl.table)) {
                    typeName = typeName + '_' + toJavaClassName(table.schema);

                    containDup = true;
                }

                let valType = tableName;
                let typeAlias;

                if (generatePojo) {
                    if ($scope.ui.generateTypeAliases && tableName.toLowerCase() !== typeName.toLowerCase())
                        typeAlias = tableName;

                    valType = _toJavaPackage(packageName) + '.' + typeName;
                }

                let _containKey = false;

                _.forEach(table.columns, function(col) {
                    const fld = dbField(col.name, SqlTypes.findJdbcType(col.type), col.nullable, col.unsigned);

                    qryFields.push({name: fld.javaFieldName, className: fld.javaType});

                    const dbName = fld.databaseFieldName;

                    if (generatePojo && $scope.ui.generateFieldAliases &&
                        SqlTypes.validIdentifier(dbName) && !SqlTypes.isKeyword(dbName) &&
                        !_.find(aliases, {field: fld.javaFieldName}) &&
                        fld.javaFieldName.toUpperCase() !== dbName.toUpperCase())
                        aliases.push({field: fld.javaFieldName, alias: dbName});

                    if (col.key) {
                        keyFields.push(fld);

                        _containKey = true;
                    }
                    else
                        valFields.push(fld);
                });

                containKey &= _containKey;
                if (table.indexes) {
                    _.forEach(table.indexes, (idx) => {
                        const idxFields = _.map(idx.fields, (idxFld) => ({
                            name: toJavaFieldName(idxFld.name),
                            direction: idxFld.sortOrder
                        }));

                        indexes.push({
                            name: idx.name,
                            indexType: 'SORTED',
                            fields: idxFields
                        });
                    });
                }

                const domainFound = _.find($scope.domains, (domain) => domain.valueType === valType);

                const batchAction = {
                    confirm: false,
                    skip: false,
                    table,
                    newDomainModel: {
                        _id: ObjectID.generate(),
                        caches: [],
                        generatePojo
                    }
                };

                if (LegacyUtils.isDefined(domainFound)) {
                    batchAction.newDomainModel._id = domainFound._id;
                    // Don't touch original caches value
                    delete batchAction.newDomainModel.caches;
                    batchAction.confirm = true;
                }

                Object.assign(batchAction.newDomainModel, {
                    tableName: typeAlias,
                    keyType: valType + 'Key',
                    valueType: valType,
                    queryMetadata: 'Configuration',
                    databaseSchema: table.schema,
                    databaseTable: tableName,
                    fields: qryFields,
                    queryKeyFields: _.map(keyFields, (field) => field.javaFieldName),
                    indexes,
                    keyFields,
                    aliases,
                    valueFields: _.isEmpty(valFields) ? keyFields.slice() : valFields
                });

                // Use Java built-in type for key.
                if ($scope.ui.builtinKeys && batchAction.newDomainModel.keyFields.length === 1) {
                    const newDomain = batchAction.newDomainModel;
                    const keyField = newDomain.keyFields[0];

                    newDomain.keyType = keyField.javaType;
                    newDomain.keyFieldName = keyField.javaFieldName;

                    if (!$scope.ui.generateKeyFields) {
                        // Exclude key column from query fields.
                        newDomain.fields = _.filter(newDomain.fields, (field) => field.name !== keyField.javaFieldName);

                        newDomain.queryKeyFields = [];
                    }

                    // Exclude key column from indexes.
                    _.forEach(newDomain.indexes, (index) => {
                        index.fields = _.filter(index.fields, (field) => field.name !== keyField.javaFieldName);
                    });

                    newDomain.indexes = _.filter(newDomain.indexes, (index) => !_.isEmpty(index.fields));
                }

                // Prepare caches for generation.
                if (table.action === IMPORT_DM_NEW_CACHE) {
                    const newCache = _.cloneDeep(this.loadedCaches[table.cacheOrTemplate]);

                    batchAction.newCache = newCache;

                    // const siblingCaches = batch.filter((a) => a.newCache).map((a) => a.newCache);
                    const siblingCaches = [];
                    newCache._id = ObjectID.generate();
                    newCache.name = uniqueName(typeName + 'Cache', this.caches.concat(siblingCaches));
                    newCache.domains = [batchAction.newDomainModel._id];
                    batchAction.newDomainModel.caches = [newCache._id];

                    // POJO store factory is not defined in template.
                    if (!newCache.cacheStoreFactory || newCache.cacheStoreFactory.kind !== 'CacheJdbcPojoStoreFactory') {
                        const dialect = $scope.importDomain.demo ? 'H2' : $scope.selectedPreset.db;

                        const catalog = $scope.importDomain.catalog;

                        newCache.cacheStoreFactory = {
                            kind: 'CacheJdbcPojoStoreFactory',
                            CacheJdbcPojoStoreFactory: {
                                dataSourceBean: 'ds' + dialect + '_' + catalog,
                                dialect,
                                implementationVersion: $scope.selectedPreset.jdbcDriverImplementationVersion
                            },
                            CacheJdbcBlobStoreFactory: { connectVia: 'DataSource' }
                        };
                    }

                    if (!newCache.readThrough && !newCache.writeThrough) {
                        newCache.readThrough = true;
                        newCache.writeThrough = true;
                    }
                }
                else {
                    const newDomain = batchAction.newDomainModel;
                    const cacheId = table.cacheOrTemplate;

                    batchAction.newDomainModel.caches = [cacheId];

                    if (!_.includes(checkedCaches, cacheId)) {
                        const cache = _.find($scope.caches, {value: cacheId}).cache;

                        // TODO: move elsewhere, make sure it still works
                        const change = LegacyUtils.autoCacheStoreConfiguration(cache, [newDomain]);

                        if (change)
                            batchAction.cacheStoreChanges = [{cacheId, change}];

                        checkedCaches.push(cacheId);
                    }
                }

                batch.push(batchAction);
            });

            /**
             * Generate message to show on confirm dialog.
             *
             * @param meta Object to confirm.
             * @returns {string} Generated message.
             */
            function overwriteMessage(meta) {
                return `
                    Domain model with name &quot;${meta.newDomainModel.databaseTable}&quot; already exists.
                    Are you sure you want to overwrite it?
                `;
            }

            const itemsToConfirm = _.filter(batch, (item) => item.confirm);

            const checkOverwrite = () => {
                if (itemsToConfirm.length > 0) {
                    return ConfirmBatch.confirm(overwriteMessage, itemsToConfirm)
                        .then(() => this.saveBatch(_.filter(batch, (item) => !item.skip)))
                        .catch(() => Messages.showError('Importing of domain models interrupted by user.'));
                }
                return this.saveBatch(batch);
            };

            const checkDuplicate = () => {
                if (containDup) {
                    Confirm.confirm('Some tables have the same name.<br/>' +
                        'Name of types for that tables will contain schema name too.')
                        .then(() => checkOverwrite());
                }
                else
                    checkOverwrite();
            };

            if (containKey)
                checkDuplicate();
            else {
                Confirm.confirm('Some tables have no primary key.<br/>' +
                    'You will need to configure key type and key fields for such tables after import complete.')
                    .then(() => checkDuplicate());
            }
        };


        $scope.importDomainNext = (form) => {
            if (!$scope.importDomainNextAvailable())
                return;

            const act = $scope.importDomain.action;

            if (act === 'drivers' && $scope.importDomain.jdbcDriversNotFound)
                importDomainModal.hide();
            else if (act === 'connect')
                _loadSchemas();
            else if (act === 'schemas')
                _loadTables();
            else if (act === 'tables')
                _selectOptions();
            else if (act === 'options')
                _saveDomainModel(form);
        };

        $scope.nextTooltipText = function() {
            const importDomainNextAvailable = $scope.importDomainNextAvailable();

            const act = $scope.importDomain.action;

            if (act === 'drivers' && $scope.importDomain.jdbcDriversNotFound)
                return 'Resolve issue with JDBC drivers<br>Close this dialog and try again';

            if (act === 'connect' && _.isNil($scope.selectedPreset.jdbcDriverClass))
                return 'Input valid JDBC driver class name';

            if (act === 'connect' && _.isNil($scope.selectedPreset.jdbcUrl))
                return 'Input valid JDBC URL';

            if (act === 'connect' || act === 'drivers')
                return 'Click to load list of schemas from database';

            if (act === 'schemas')
                return importDomainNextAvailable ? 'Click to load list of tables from database' : 'Select schemas to continue';

            if (act === 'tables')
                return importDomainNextAvailable ? 'Click to show import options' : 'Select tables to continue';

            if (act === 'options')
                return 'Click to import domain model for selected tables';

            return 'Click to continue';
        };

        $scope.prevTooltipText = function() {
            const act = $scope.importDomain.action;

            if (act === 'schemas')
                return $scope.importDomain.demo ? 'Click to return on demo description step' : 'Click to return on connection configuration step';

            if (act === 'tables')
                return 'Click to return on schemas selection step';

            if (act === 'options')
                return 'Click to return on tables selection step';
        };

        $scope.importDomainNextAvailable = function() {
            switch ($scope.importDomain.action) {
                case 'connect':
                    return !_.isNil($scope.selectedPreset.jdbcDriverClass) && !_.isNil($scope.selectedPreset.jdbcUrl);

                case 'schemas':
                    return _.isEmpty($scope.importDomain.schemas) || !!get('importDomain.schemasToUse.length')($scope);

                case 'tables':
                    return !!$scope.importDomain.tablesToUse.length;

                default:
                    return true;
            }
        };

        $scope.importDomainPrev = function() {
            $scope.importDomain.button = 'Next';

            if ($scope.importDomain.action === 'options') {
                $scope.importDomain.action = 'tables';
                $scope.importDomain.info = INFO_SELECT_TABLES;
            }
            else if ($scope.importDomain.action === 'tables' && $scope.importDomain.schemas.length > 0) {
                $scope.importDomain.action = 'schemas';
                $scope.importDomain.info = INFO_SELECT_SCHEMAS;
            }
            else {
                $scope.importDomain.action = 'connect';
                $scope.importDomain.info = INFO_CONNECT_TO_DB;
            }
        };

        const demo = $root.IgniteDemoMode;

        $scope.importDomain = {
            demo,
            action: demo ? 'connect' : 'drivers',
            jdbcDriversNotFound: demo,
            schemas: [],
            allSchemasSelected: false,
            tables: [],
            allTablesSelected: false,
            button: 'Next',
            info: ''
        };

        $scope.importDomain.loadingOptions = LOADING_JDBC_DRIVERS;

        const fetchDomainData = () => {
            return agentMgr.awaitAgent()
                .then(() => {
                    ActivitiesData.post({
                        group: 'configuration',
                        action: 'configuration/import/model'
                    });

                    return true;
                })
                .then(() => {
                    if (demo) {
                        $scope.ui.packageNameUserInput = $scope.ui.packageName;
                        $scope.ui.packageName = 'model';

                        return;
                    }

                    // Get available JDBC drivers via agent.
                    Loading.start('importDomainFromDb');

                    $scope.jdbcDriverJars = [];
                    $scope.ui.selectedJdbcDriverJar = {};

                    return agentMgr.drivers()
                        .then((drivers) => {
                            $scope.ui.packageName = $scope.ui.packageNameUserInput;

                            if (drivers && drivers.length > 0) {
                                drivers = _.sortBy(drivers, 'jdbcDriverJar');

                                _.forEach(drivers, (drv) => {
                                    $scope.jdbcDriverJars.push({
                                        label: drv.jdbcDriverJar,
                                        value: {
                                            jdbcDriverJar: drv.jdbcDriverJar,
                                            jdbcDriverClass: drv.jdbcDriverCls,
                                            jdbcDriverImplementationVersion: drv.jdbcDriverImplVersion
                                        }
                                    });
                                });

                                $scope.ui.selectedJdbcDriverJar = $scope.jdbcDriverJars[0].value;

                                $scope.importDomain.action = 'connect';
                                $scope.importDomain.tables = [];
                                this.selectedTables = [];
                            }
                            else {
                                $scope.importDomain.jdbcDriversNotFound = true;
                                $scope.importDomain.button = 'Cancel';
                            }
                        })
                        .then(() => {
                            $scope.importDomain.info = INFO_CONNECT_TO_DB;

                            Loading.finish('importDomainFromDb');
                        });
                });
        };

        this.agentIsAvailable$ = this.agentMgr.connectionSbj.pipe(
            pluck('state'),
            distinctUntilChanged(),
            map((state) => state !== 'AGENT_DISCONNECTED')
        );

        this.domainData$ = this.agentIsAvailable$.pipe(
            switchMap((agentIsAvailable) => {
                if (!agentIsAvailable)
                    return of(EMPTY);

                return from(fetchDomainData());
            })
        );

        this.subscribers$ = merge(
            this.subscription,
            this.domainData$
        ).subscribe();

        $scope.$watch('ui.selectedJdbcDriverJar', function(val) {
            if (val && !$scope.importDomain.demo) {
                const foundPreset = _findPreset(val);

                const selectedPreset = $scope.selectedPreset;

                selectedPreset.db = foundPreset.db;
                selectedPreset.jdbcDriverJar = foundPreset.jdbcDriverJar;
                selectedPreset.jdbcDriverClass = foundPreset.jdbcDriverClass;
                selectedPreset.jdbcDriverImplementationVersion = foundPreset.jdbcDriverImplementationVersion;
                selectedPreset.jdbcUrl = foundPreset.jdbcUrl;
                selectedPreset.user = foundPreset.user;
            }
        }, true);
    }

    _fillCommonCachesOrTemplates(item) {
        return (action) => {
            if (item.cachesOrTemplates)
                item.cachesOrTemplates.length = 0;
            else
                item.cachesOrTemplates = [];

            if (action === IMPORT_DM_NEW_CACHE)
                item.cachesOrTemplates.push(...CACHE_TEMPLATES);

            if (!_.isEmpty(this.$scope.caches)) {
                item.cachesOrTemplates.push(...this.$scope.caches);
                this.onCacheSelect(item.cachesOrTemplates[0].value);
            }

            if (
                !_.find(item.cachesOrTemplates, {value: item.cacheOrTemplate}) &&
                item.cachesOrTemplates.length
            )
                item.cacheOrTemplate = item.cachesOrTemplates[0].value;
        };
    }

    schemasColumnDefs = [
        {
            name: 'name',
            displayName: 'Name',
            field: 'name',
            enableHiding: false,
            sort: {direction: 'asc', priority: 0},
            filter: {
                placeholder: 'Filter by Name…'
            },
            visible: true,
            sortingAlgorithm: naturalCompare,
            minWidth: 165
        }
    ];

    tablesColumnDefs = [
        {
            name: 'schema',
            displayName: 'Schema',
            field: 'schema',
            enableHiding: false,
            enableFiltering: false,
            sort: {direction: 'asc', priority: 0},
            visible: true,
            sortingAlgorithm: naturalCompare,
            minWidth: 100
        },
        {
            name: 'table',
            displayName: 'Table',
            field: 'table',
            enableHiding: false,
            enableFiltering: true,
            filter: {
                placeholder: 'Filter by Table…'
            },
            visible: true,
            sortingAlgorithm: naturalCompare,
            minWidth: 200
        },
        {
            name: 'action',
            displayName: 'Action',
            field: 'action',
            enableHiding: false,
            enableFiltering: false,
            cellTemplate: `
                <tables-action-cell
                    table='row.entity'
                    on-edit-start='grid.appScope.$ctrl.$scope.startEditDbTableCache($event)'
                    on-cache-select='grid.appScope.$ctrl.onCacheSelect($event)'
                    caches='grid.appScope.$ctrl._importCachesOrTemplates'
                    import-actions='grid.appScope.$ctrl.$scope.importActions'
                ></tables-action-cell>
            `,
            visible: true,
            minWidth: 450
        }
    ];
}

export const component = {
    name: 'modalImportModels',
    controller: ModalImportModels,
    templateUrl,
    bindings: {
        onHide: '&',
        clusterID: '<clusterId'
    }
};
