/*
 * 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'
    }
};
