import applicationTypes from './application-types.js';
import authenticationTypes from './authentication-types.js';
import databaseTypes from './database-types.js';
import applicationOptions from './application-options.js';
import cacheTypes from './cache-types.js';
import serviceDiscoveryTypes from './service-discovery-types.js';
import clientFrameworkTypes from './client-framework-types.js';
import buildToolTypes from './build-tool-types.js';
import { MESSAGE_BROKER, MESSAGE_BROKER_NO } from '../../generators/server/options/index.mjs';
import ormToolTypes from './orm-tool-types.js';
const { MONOLITH, MICROSERVICE, GATEWAY } = applicationTypes;
const { CONSUL } = serviceDiscoveryTypes;
const { COUCHBASE, CASSANDRA, MONGODB, NEO4J, SQL, POSTGRESQL } = databaseTypes;
const NO_DATABASE_TYPE = databaseTypes.NO;
const { OptionNames, OptionValues } = applicationOptions;
const { JWT, OAUTH2 } = authenticationTypes;
const { NO: NO_CLIENT_FRAMEWORK, VUE, MOBILE } = clientFrameworkTypes;
const { EHCACHE, HAZELCAST } = cacheTypes;
const NO_CACHE_PROVIDER = cacheTypes.NO;
const NO_SERVICE_DISCOVERY = serviceDiscoveryTypes.NO;
const { MAVEN } = buildToolTypes;
const { APPLICATION_TYPE, AUTHENTICATION_TYPE, BASE_NAME, BUILD_TOOL, CACHE_PROVIDER, CLIENT_FRAMEWORK, CLIENT_THEME, CLIENT_THEME_VARIANT, WITH_ADMIN_UI, WITH_WEBSITE, DATABASE_TYPE, DEV_DATABASE_TYPE, DTO_SUFFIX, ENABLE_HIBERNATE_CACHE, ENABLE_SWAGGER_CODEGEN, ENABLE_TRANSLATION, ENTITY_SUFFIX, JHI_PREFIX, LANGUAGES, NATIVE_LANGUAGE, PACKAGE_FOLDER, PACKAGE_NAME, PROD_DATABASE_TYPE, REACTIVE, SEARCH_ENGINE, SERVER_PORT, SERVICE_DISCOVERY_TYPE, SKIP_CLIENT, SKIP_USER_MANAGEMENT, TEST_FRAMEWORKS, WEBSOCKET, ENABLE_GRADLE_ENTERPRISE, GRADLE_ENTERPRISE_HOST, MOBILE_FRAMEWORK, MOBILE_THEME, ORM_TOOL, USER_ID_TYPE, } = OptionNames;
const commonDefaultOptions = {
    [AUTHENTICATION_TYPE]: JWT,
    [BUILD_TOOL]: MAVEN,
    [DTO_SUFFIX]: OptionValues[DTO_SUFFIX],
    [ENABLE_SWAGGER_CODEGEN]: OptionValues[ENABLE_SWAGGER_CODEGEN],
    [ENABLE_TRANSLATION]: OptionValues[ENABLE_TRANSLATION],
    [ENTITY_SUFFIX]: OptionValues[ENTITY_SUFFIX],
    [JHI_PREFIX]: OptionValues[JHI_PREFIX],
    [MESSAGE_BROKER]: MESSAGE_BROKER_NO,
    [SEARCH_ENGINE]: OptionValues[SEARCH_ENGINE].no,
    [WEBSOCKET]: OptionValues[WEBSOCKET].no,
    [ORM_TOOL]: ormToolTypes.MYBATIS,
    [USER_ID_TYPE]: 'Long',
    skipJhipsterDependencies: false,
};
export function getConfigWithDefaults(customOptions = {}) {
    const applicationType = typeof customOptions === 'string' ? customOptions : customOptions.applicationType;
    if (applicationType === GATEWAY) {
        return getConfigForGatewayApplication(customOptions);
    }
    if (applicationType === MICROSERVICE) {
        return getConfigForMicroserviceApplication(customOptions);
    }
    return getConfigForMonolithApplication(customOptions);
}
export function getConfigForClientApplication(options = {}) {
    if (options[SKIP_CLIENT]) {
        options[CLIENT_FRAMEWORK] = NO_CLIENT_FRAMEWORK;
    }
    if (options[OptionNames.MICROFRONTEND] === undefined) {
        options[OptionNames.MICROFRONTEND] = Boolean(options[OptionNames.MICROFRONTENDS]?.length);
    }
    const clientFramework = options[CLIENT_FRAMEWORK];
    if (clientFramework !== NO_CLIENT_FRAMEWORK) {
        if (!options[CLIENT_THEME]) {
            options[CLIENT_THEME] = OptionValues[CLIENT_THEME];
            options[CLIENT_THEME_VARIANT] = '';
        }
        else if (options[CLIENT_THEME] !== OptionValues[CLIENT_THEME] && !options[CLIENT_THEME_VARIANT]) {
            options[CLIENT_THEME_VARIANT] = 'primary';
        }
    }
    return options;
}
export function getConfigForAuthenticationType(options = {}) {
    if (typeof options[SKIP_USER_MANAGEMENT] !== 'boolean') {
        if (options[AUTHENTICATION_TYPE] === OAUTH2) {
            options[SKIP_USER_MANAGEMENT] = true;
        }
        else {
            options[SKIP_USER_MANAGEMENT] = OptionValues[SKIP_USER_MANAGEMENT];
        }
    }
    return options;
}
export function getConfigForPackageName(options = {}) {
    if (!options[PACKAGE_NAME] && !options[PACKAGE_FOLDER]) {
        options[PACKAGE_FOLDER] = OptionValues[PACKAGE_FOLDER];
    }
    if (!options[PACKAGE_NAME] && options[PACKAGE_FOLDER]) {
        options[PACKAGE_NAME] = options[PACKAGE_FOLDER].replace(/\//g, '.');
    }
    if (!options[PACKAGE_FOLDER] && options[PACKAGE_NAME]) {
        options[PACKAGE_FOLDER] = options[PACKAGE_NAME].replace(/\./g, '/');
    }
    return options;
}
export function getConfigForCacheProvider(options = {}) {
    if (options[REACTIVE]) {
        options[CACHE_PROVIDER] = NO_CACHE_PROVIDER;
    }
    return options;
}
export function getConfigForReactive(options = {}) {
    if (options[REACTIVE] === undefined) {
        options[REACTIVE] = false;
    }
    return options;
}
export function getConfigForTranslation(options = {}) {
    if (options[ENABLE_TRANSLATION] === undefined) {
        options[ENABLE_TRANSLATION] = true;
    }
    if (options[NATIVE_LANGUAGE] === undefined) {
        options[NATIVE_LANGUAGE] = 'zh-cn';
    }
    if (options[ENABLE_TRANSLATION] && options[LANGUAGES] === undefined) {
        options[LANGUAGES] = [];
    }
    return options;
}
export function getConfigForDatabaseType(options = {}) {
    if (options[DATABASE_TYPE] === undefined) {
        options[DATABASE_TYPE] = SQL;
    }
    if (options[DATABASE_TYPE] === SQL) {
        if (options[PROD_DATABASE_TYPE] === undefined) {
            options[PROD_DATABASE_TYPE] = POSTGRESQL;
        }
        if (options[DEV_DATABASE_TYPE] === undefined) {
            options[DEV_DATABASE_TYPE] = options[PROD_DATABASE_TYPE];
        }
    }
    else if ([MONGODB, COUCHBASE, CASSANDRA, NEO4J, NO_DATABASE_TYPE].includes(options[DATABASE_TYPE])) {
        if (NO_DATABASE_TYPE !== options[DATABASE_TYPE]) {
            options[ENABLE_HIBERNATE_CACHE] = false;
        }
    }
    if (options[REACTIVE]) {
        options[ENABLE_HIBERNATE_CACHE] = false;
    }
    if (options[ENABLE_HIBERNATE_CACHE] === undefined) {
        options[ENABLE_HIBERNATE_CACHE] = true;
    }
    return options;
}
export function getServerConfigForMonolithApplication(customOptions = {}) {
    const options = {
        ...commonDefaultOptions,
        [CACHE_PROVIDER]: EHCACHE,
        [CLIENT_FRAMEWORK]: VUE,
        [MOBILE_FRAMEWORK]: MOBILE,
        [SERVER_PORT]: OptionValues[SERVER_PORT],
        [SERVICE_DISCOVERY_TYPE]: NO_SERVICE_DISCOVERY,
        [WITH_ADMIN_UI]: true,
        [WITH_WEBSITE]: false,
        [ORM_TOOL]: ormToolTypes.MYBATIS,
        [USER_ID_TYPE]: 'Long',
        ...customOptions,
    };
    return {
        ...options,
        [APPLICATION_TYPE]: MONOLITH,
    };
}
export function getConfigForMonolithApplication(customOptions = {}) {
    let options = getServerConfigForMonolithApplication(customOptions);
    options = getConfigForClientApplication(options);
    options = getConfigForPackageName(options);
    options = getConfigForCacheProvider(options);
    options = getConfigForDatabaseType(options);
    options = getConfigForReactive(options);
    options = getConfigForTranslation(options);
    return getConfigForAuthenticationType(options);
}
export function getServerConfigForGatewayApplication(customOptions = {}) {
    const options = {
        ...commonDefaultOptions,
        [CLIENT_FRAMEWORK]: VUE,
        [MOBILE_FRAMEWORK]: MOBILE,
        [SERVER_PORT]: OptionValues[SERVER_PORT],
        [SERVICE_DISCOVERY_TYPE]: CONSUL,
        [WITH_ADMIN_UI]: true,
        [WITH_WEBSITE]: false,
        [ORM_TOOL]: ormToolTypes.HIBERNATE,
        ...customOptions,
    };
    options[CACHE_PROVIDER] = NO_CACHE_PROVIDER;
    options[ENABLE_HIBERNATE_CACHE] = false;
    return {
        ...options,
        [REACTIVE]: true,
        [APPLICATION_TYPE]: GATEWAY,
    };
}
export function getConfigForGatewayApplication(customOptions = {}) {
    let options = getServerConfigForGatewayApplication(customOptions);
    options = getConfigForClientApplication(options);
    options = getConfigForPackageName(options);
    options = getConfigForCacheProvider(options);
    options = getConfigForDatabaseType(options);
    options = getConfigForReactive(options);
    options = getConfigForTranslation(options);
    return getConfigForAuthenticationType(options);
}
export function getServerConfigForMicroserviceApplication(customOptions = {}) {
    const DEFAULT_SERVER_PORT = 8081;
    const options = {
        ...commonDefaultOptions,
        [CACHE_PROVIDER]: HAZELCAST,
        [SERVER_PORT]: DEFAULT_SERVER_PORT,
        [SERVICE_DISCOVERY_TYPE]: CONSUL,
        [SKIP_USER_MANAGEMENT]: true,
        [CLIENT_FRAMEWORK]: NO_CLIENT_FRAMEWORK,
        [ORM_TOOL]: ormToolTypes.MYBATIS,
        [USER_ID_TYPE]: 'Long',
        ...customOptions,
    };
    options[WITH_ADMIN_UI] = false;
    options[WITH_WEBSITE] = false;
    return {
        ...options,
        [APPLICATION_TYPE]: MICROSERVICE,
    };
}
export function getConfigForMicroserviceApplication(customOptions = {}) {
    let options = getServerConfigForMicroserviceApplication(customOptions);
    options = getConfigForClientApplication(options);
    options = getConfigForPackageName(options);
    options = getConfigForCacheProvider(options);
    options = getConfigForDatabaseType(options);
    options = getConfigForReactive(options);
    options = getConfigForTranslation(options);
    return getConfigForAuthenticationType(options);
}
export function getDefaultConfigForNewApplication(customOptions = {}) {
    const options = {
        ...commonDefaultOptions,
        [BASE_NAME]: OptionValues[BASE_NAME],
        [LANGUAGES]: OptionValues[LANGUAGES],
        [TEST_FRAMEWORKS]: [],
        [ENABLE_GRADLE_ENTERPRISE]: OptionValues[ENABLE_GRADLE_ENTERPRISE],
        [GRADLE_ENTERPRISE_HOST]: OptionValues[GRADLE_ENTERPRISE_HOST],
        ...customOptions,
    };
    return getConfigWithDefaults(options);
}
