'use strict';
// Advanced options for the config command
const portfinder = require('portfinder');
const toString = require('lodash/toString');
const includes = require('lodash/includes');
const validator = require('validator');
const url = require('url');

const BASE_PORT = '2368';
const knownMailServices = [
    'AOL', 'DynectEmail', 'Gmail', 'hot.ee', 'Hotmail', 'iCloud', 'mail.ee', 'Mail.Ru', 'Mailgun',
    'Mailjet', 'Mandrill', 'Postmark', 'QQ', 'QQex (Tencent Business Email)', 'SendGrid',
    'SendCloud', 'SES', 'Yahoo', 'yandex', 'Zoho'
];

/*
    Note: these options are handled serially, i.e. one after the other.
    The `default` function in each option is passed the current config. Because the
    options are handled serially, each default function can be certain that that previous
    options will have been handled prior to it being run.
 */
module.exports = {
    url: {
        description: 'Blog URL with protocol E.g. http://loveghost.com',
        validate: value => validator.isURL(value, {require_protocol: true}) ||
            'Invalid URL. Your URL should include a protocol, E.g. http://my-ghost-blog.com',
        type: 'string',
        group: 'Ghost Options:'
    },
    adminUrl: {
        description: 'URL for the admin client, if different than the normal URL',
        configPath: 'admin.url',
        validate: value => validator.isURL(value, {require_protocol: true}) ||
            'Invalid URL. Your URL should include a protocol, E.g. http://my-ghost-blog.com',
        type: 'string',
        group: 'Ghost Options:'
    },
    port: {
        description: 'Port ghost should listen on',
        configPath: 'server.port',
        validate: value => {
            value = toString(value);

            if (!validator.isInt(value, {allow_leading_zeros: false})) {
                return 'Port must be an integer.';
            }

            return portfinder.getPortPromise({port: value}).then((port) => {
                return (port === value) || `Port '${value}' is in use.`;
            });
        },
        defaultValue: config => {
            let port = url.parse(config.get('url')).port || BASE_PORT;
            return portfinder.getPortPromise({port: parseInt(port)});
        },
        default: 2368,
        type: 'number',
        group: 'Ghost Options:'
    },
    ip: {
        description: 'IP ghost should listen on',
        configPath: 'server.host',
        default: '127.0.0.1',
        type: 'string',
        group: 'Ghost Options:'
    },

    // Database options
    db: {
        description: 'Type of database Ghost should use E.g. mysql or sqlite3',
        validate: value => includes(['sqlite3', 'mysql'], value),
        configPath: 'database.client',
        type: 'string',
        group: 'Database Options:'
    },
    dbpath: {
        description: 'Path to the database file (sqlite3 only)',
        configPath: 'database.connection.filename',
        type: 'string',
        group: 'Database Options:'
    },
    dbhost: {
        description: 'Database host',
        configPath: 'database.connection.host',
        type: 'string',
        group: 'Database Options:'
    },
    dbuser: {
        description: 'Database username',
        configPath: 'database.connection.user',
        type: 'string',
        group: 'Database Options:'
    },
    dbpass: {
        description: 'Database password',
        configPath: 'database.connection.password',
        type: 'string',
        group: 'Database Options:'
    },
    dbname: {
        description: 'Database name',
        configPath: 'database.connection.database',
        type: 'string',
        group: 'Database Options:'
    },

    // Mail options:
    // Designed to support the most common mail configs, more advanced configs will require editing the config file
    mail: {
        description: 'Mail transport, E.g SMTP, Sendmail or Direct',
        validate: value => includes(['SMTP', 'Sendmail', 'Direct'], value),
        configPath: 'mail.transport',
        type: 'string',
        default: 'Direct',
        group: 'Mail Options:'
    },
    mailservice: {
        description: 'Mail service (used with SMTP transport), E.g. Mailgun, Sendgrid, Gmail, SES...',
        configPath: 'mail.options.service',
        validate: value => includes(knownMailServices, value),
        type: 'string',
        group: 'Mail Options:'
    },
    mailuser: {
        description: 'Mail auth user (used with SMTP transport)',
        configPath: 'mail.options.auth.user',
        type: 'string',
        implies: 'mailpass',
        group: 'Mail Options:'
    },
    mailpass: {
        description: 'Mail auth pass (used with SMTP transport)',
        configPath: 'mail.options.auth.pass',
        type: 'string',
        implies: 'mailuser',
        group: 'Mail Options:'
    },
    mailhost: {
        description: 'Mail host (used with SMTP transport)',
        configPath: 'mail.options.host',
        type: 'string',
        group: 'Mail Options:'
    },
    mailport: {
        description: 'Mail port (used with SMTP transport)',
        configPath: 'mail.options.port',
        type: 'number',
        group: 'Mail Options:'
    },

    // Log options
    log: {
        description: 'Transport to send Ghost log output to',
        configPath: 'logging.transports',
        filter: (value, transports) => {
            transports.push(value);
            return transports;
        },
        default: ['file', 'stdout'], // used for config command handling
        type: 'array',
        group: 'Ghost Options:'
    },

    // Customise how Ghost-CLI runs
    process: {
        description: 'Type of process manager to run Ghost with',
        defaultValue: (c, env) => env === 'production' ? 'systemd' : 'local',
        type: 'string',
        group: 'Service Options:'
    }
};

@@ -2975,32 +2975,333 @@
 tabase Options:'
+,%0A        defaultValue: (config, environment) =%3E %7B%0A            if (config.get('database.client') !== 'sqlite3') %7B%0A                return null;%0A            %7D%0A%0A            let dbFile = (environment === 'production') ? 'ghost.db' : 'ghost-dev.db';%0A            return %60./content/data/$%7BdbFile%7D%60;%0A        %7D
 %0A    %7D,%0A    dbho

add default dbpath when db is sqlite