/**
 * config.js
 * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
 *
 * Contact:
 * DongHee Yang <donghee.yang@samsung.com>
 * Sungmin Kim <sm.art.kim@samsung.com>
 * Jiil Hyoun <jiil.hyoun@samsung.com>
 * Jonghwan Park <iwin100.park@samsung.com>
 * Kitae Kim <kt920.kim@samsung.com>
 *
 * Licensed 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.
 *
 * Contributors:
 * - S-Core Co., Ltd
**/

var fs = require('fs');
var extfs = require('fs-extra');
var path = require('path');
var utils = require('../lib/utils');
var yaml = require('js-yaml');


var configRootDir = getConfigRootDir();
var CONFIG_FILE = 'config.yaml';

/**
 * @module core/config
 */

/**
 * @function getServerConfigRootDir
 * @param {module:core/base-server.BaseServer} server - server
 * @returns {string}
 * @memberOf module:core/config
 */

module.exports.getServerConfigRootDir = function (server) {
    return path.join(configRootDir, server.id);
};

module.exports.getBaseConfig = getBaseConfig;
function getBaseConfig(options) {
    var cOsType = (process.platform === 'win32') ? 'windows' : 'posix'
    return {
        id: options.id,
        host: options.host,
        port: options.port,
        type: options.type,
        os_type: cOsType,
        config_root_dir: getConfigRootDir(),
        log_file: utils.osPathJoin(cOsType, [getConfigRootDir(), options.id, 'log']),
        'dfs-path': utils.osPathJoin(cOsType, [getConfigRootDir(), options.id, 'share']),
        'dfs-size': 1024 * 1024 * 1024 // 1G
    };
}

/**
 * @function openServerConfig
 * @param {module:core/base-server.BaseServer} server - server
 * @returns {string}
 * @memberOf module:core/config
 */

module.exports.openServerConfig = function (server, config) {
    var configPath = path.join(configRootDir, server.id, CONFIG_FILE);

    if (fs.existsSync(configPath)) {
        return loadServerConfig(server, configPath);
    } else {
        return createServerConfig(server, config);
    }
};

/**
 * @function newServerConfig
 * @param {module:core/base-server.BaseServer} server - server
 * @returns {string}
 * @memberOf module:core/config
 */

module.exports.newServerConfig = newServerConfig;
function newServerConfig(server, configData) {
    var config = new ServerConfig(server);

    if (configData) {
        for (var key in configData) {
            config.set(key, configData[key]);
        }
    }

    return config;
}

/**
 * @function getConfigDir
 * @returns  {string}
 * @memberOf module:core/config
 */

module.exports.getConfigDir = function () {
    return getConfigRootDir();
};


/**
 * @function saveServerConfig
 * @param {module:core/base-server.BaseServer} server - server
 * @returns {string}
 * @memberOf module:core/config
 */

module.exports.saveServerConfig = function (server) {
    var configPath = path.join(configRootDir, server.id, CONFIG_FILE);

    fs.writeFileSync(configPath, server.config.toString());
};


function getConfigRootDir() {
    var configPath;
    if (utils.isWindows()) {
        configPath = utils.getLocalAppDataPath().replace(/\\/g, '\\\\\\\\');
    } else {
        configPath = utils.getHomePath();
    }

    return path.join(configPath, '.dibs');
}

/**
 * @typedef {object} config
 * @property {string} log_file
 * @memberOf module:core/config
 */

/**
 * @constructor
 * @param {module:core/base-server.BaseServer} server
 * @memberOf module:core/config
 */

function ServerConfig(server) {
    /** @type {module:core/config.config} */
    var config = {};

    // set server dependent default setting
    if (server.getDefaultConfiguration !== undefined) {
        var defaults = server.getDefaultConfiguration(getBaseConfig({
            id: server.id,
            host: server.host,
            port: server.port,
            type: server.type
        }));
        for (var key in defaults) {
            config[key] = defaults[key];
        }
    }

    /**
     * @method set
     * @param {string} key
     * @param {string} val
     * @return {undefined}
     * @memberOf module:core/config.ServerConfig
     */
    this.set = function (key, val) {
        if (val !== undefined) {
            config[key] = val;
        } else {
            delete config[key];
        }
        return;
    };

    /**
     * @method get
     * @param {string} key
     * @return {string}
     * @memberOf module:core/config.ServerConfig
     */
    this.get = function (key) {
        return config[key];
    };

    /**
     * @method toString
     * @return {string}
     * @memberOf module:core/config.ServerConfig
     */
    this.toString = function () {
        return yaml.dump(config);
    };

    this.getConfigData = function () {
        return config;
    };
}


module.exports.createServerConfig = createServerConfig;
function createServerConfig(server, configData) {
    var serverConfigDir = path.join(configRootDir, server.id);
    var configPath = path.join(serverConfigDir, CONFIG_FILE);
    var config = newServerConfig(server, configData);

    // create directorty
    extfs.mkdirpSync(serverConfigDir);

    // create directories and write config file
    fs.writeFileSync(configPath, config.toString());

    return config;
}


function loadServerConfig( server, configPath ) {
	var config = new ServerConfig( server );
	var readConfig = {};
    try{
	    readConfig = yaml.safeLoad(fs.readFileSync(configPath,'utf-8'));
    } catch (e) {
        console.log('load file ' + configPath + ' failed')
        console.log(e);
        throw e;
    }

    for (var key in readConfig) {
        config.set(key, readConfig[key]);
    }

    return config;
}
