/*
 * 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.
 *
*/

/* eslint no-control-regex: 0 */

var fs = require('fs-extra');
var path = require('path');

var modules = {};
var addProperty = require('../util/addProperty');

// Use delay loading to ensure plist and other node modules to not get loaded
// on Android, Windows platforms
addProperty(module, 'bplist', 'bplist-parser', modules);
addProperty(module, 'et', 'elementtree', modules);
addProperty(module, 'glob', 'glob', modules);
addProperty(module, 'plist', 'plist', modules);
addProperty(module, 'plist_helpers', '../util/plist-helpers', modules);
addProperty(module, 'xml_helpers', '../util/xml-helpers', modules);

/******************************************************************************
* ConfigFile class
*
* Can load and keep various types of config files. Provides some functionality
* specific to some file types such as grafting XML children. In most cases it
* should be instantiated by ConfigKeeper.
*
* For plugin.xml files use as:
* plugin_config = self.config_keeper.get(plugin_dir, '', 'plugin.xml');
*
* TODO: Consider moving it out to a separate file and maybe partially with
* overrides in platform handlers.
******************************************************************************/
function ConfigFile (project_dir, platform, file_tag) {
    this.project_dir = project_dir;
    this.platform = platform;
    this.file_tag = file_tag;
    this.is_changed = false;

    this.load();
}

// ConfigFile.load()
ConfigFile.prototype.load = ConfigFile_load;
function ConfigFile_load () {
    var self = this;

    // config file may be in a place not exactly specified in the target
    var filepath = self.filepath = resolveConfigFilePath(self.project_dir, self.platform, self.file_tag);

    if (!filepath || !fs.existsSync(filepath)) {
        self.exists = false;
        return;
    }
    self.exists = true;
    self.mtime = fs.statSync(self.filepath).mtime;

    var ext = path.extname(filepath);
    // Windows8 uses an appxmanifest, and wp8 will likely use
    // the same in a future release
    if (ext === '.xml' || ext === '.appxmanifest' || ext === '.storyboard') {
        self.type = 'xml';
        self.data = modules.xml_helpers.parseElementtreeSync(filepath);
    } else {
        // plist file
        self.type = 'plist';
        // TODO: isBinaryPlist() reads the file and then parse re-reads it again.
        //       We always write out text plist, not binary.
        //       Do we still need to support binary plist?
        //       If yes, use plist.parseStringSync() and read the file once.
        self.data = isBinaryPlist(filepath) ?
            modules.bplist.parseBuffer(fs.readFileSync(filepath))[0] :
            modules.plist.parse(fs.readFileSync(filepath, 'utf8'));
    }
}

ConfigFile.prototype.save = function ConfigFile_save () {
    var self = this;
    if (self.type === 'xml') {
        fs.writeFileSync(self.filepath, self.data.write({ indent: 4 }), 'utf-8');
    } else {
        // plist
        var regExp = new RegExp('<string>[ \t\r\n]+?</string>', 'g');
        fs.writeFileSync(self.filepath, modules.plist.build(self.data).replace(regExp, '<string></string>'));
    }
    self.is_changed = false;
};

ConfigFile.prototype.graft_child = function ConfigFile_graft_child (selector, xml_child) {
    var self = this;
    var filepath = self.filepath;
    var result;
    if (self.type === 'xml') {
        var xml_to_graft = [modules.et.XML(xml_child.xml)];
        switch (xml_child.mode) {
        case 'merge':
            result = modules.xml_helpers.graftXMLMerge(self.data, xml_to_graft, selector, xml_child);
            break;
        case 'overwrite':
            result = modules.xml_helpers.graftXMLOverwrite(self.data, xml_to_graft, selector, xml_child);
            break;
        case 'remove':
            result = modules.xml_helpers.pruneXMLRemove(self.data, selector, xml_to_graft);
            break;
        default:
            result = modules.xml_helpers.graftXML(self.data, xml_to_graft, selector, xml_child.after);
        }
        if (!result) {
            throw new Error('Unable to graft xml at selector "' + selector + '" from "' + filepath + '" during config install');
        }
    } else {
        // plist file
        result = modules.plist_helpers.graftPLIST(self.data, xml_child.xml, selector);
        if (!result) {
            throw new Error('Unable to graft plist "' + filepath + '" during config install');
        }
    }
    self.is_changed = true;
};

ConfigFile.prototype.prune_child = function ConfigFile_prune_child (selector, xml_child) {
    var self = this;
    var filepath = self.filepath;
    var result;
    if (self.type === 'xml') {
        var xml_to_graft = [modules.et.XML(xml_child.xml)];
        switch (xml_child.mode) {
        case 'merge':
        case 'overwrite':
            result = modules.xml_helpers.pruneXMLRestore(self.data, selector, xml_child);
            break;
        case 'remove':
            result = modules.xml_helpers.pruneXMLRemove(self.data, selector, xml_to_graft);
            break;
        default:
            result = modules.xml_helpers.pruneXML(self.data, xml_to_graft, selector);
        }
    } else {
        // plist file
        result = modules.plist_helpers.prunePLIST(self.data, xml_child.xml, selector);
    }
    if (!result) {
        var err_msg = 'Pruning at selector "' + selector + '" from "' + filepath + '" went bad.';
        throw new Error(err_msg);
    }
    self.is_changed = true;
};

// Some config-file target attributes are not qualified with a full leading directory, or contain wildcards.
// Resolve to a real path in this function.
// TODO: getIOSProjectname is slow because of glob, try to avoid calling it several times per project.
function resolveConfigFilePath (project_dir, platform, file) {
    var filepath = path.join(project_dir, file);
    var matches;

    file = path.normalize(file);

    if (file.includes('*')) {
        // handle wildcards in targets using glob.
        matches = modules.glob.sync(path.join(project_dir, '**', file));
        if (matches.length) filepath = matches[0];

        // [CB-5989] multiple Info.plist files may exist. default to $PROJECT_NAME-Info.plist
        if (matches.length > 1 && file.includes('-Info.plist')) {
            var plistName = getIOSProjectname(project_dir) + '-Info.plist';
            for (var i = 0; i < matches.length; i++) {
                if (matches[i].includes(plistName)) {
                    filepath = matches[i];
                    break;
                }
            }
        }
        return filepath;
    }

    // XXX this checks for android studio projects
    // only if none of the options above are satisfied does this get called
    // TODO: Move this out of cordova-common and into the platforms somehow
    if (platform === 'android' && !fs.existsSync(filepath)) {
        var config_file;
        if (file === 'AndroidManifest.xml') {
            filepath = path.join(project_dir, 'app', 'src', 'main', 'AndroidManifest.xml');
        } else if (file.endsWith('config.xml')) {
            filepath = path.join(project_dir, 'app', 'src', 'main', 'res', 'xml', 'config.xml');
        } else if (file.endsWith('strings.xml')) {
            // Plugins really shouldn't mess with strings.xml, since it's able to be localized
            filepath = path.join(project_dir, 'app', 'src', 'main', 'res', 'values', 'strings.xml');
        } else if (file.includes(path.join('res', 'values'))) {
            config_file = path.basename(file);
            filepath = path.join(project_dir, 'app', 'src', 'main', 'res', 'values', config_file);
        } else if (file.includes(path.join('res', 'xml'))) {
            // Catch-all for all other stored XML configuration in legacy plugins
            config_file = path.basename(file);
            filepath = path.join(project_dir, 'app', 'src', 'main', 'res', 'xml', config_file);
        }
        return filepath;
    }

    // special-case config.xml target that is just "config.xml" for other platforms. This should
    // be resolved to the real location of the file.
    // TODO: Move this out of cordova-common into platforms
    if (file === 'config.xml') {
        if (platform === 'ubuntu') {
            filepath = path.join(project_dir, 'config.xml');
        } else if (platform === 'ios' || platform === 'osx') {
            filepath = path.join(
                project_dir,
                module.exports.getIOSProjectname(project_dir),
                'config.xml'
            );
        } else {
            matches = modules.glob.sync(path.join(project_dir, '**', 'config.xml'));
            if (matches.length) filepath = matches[0];
        }
        return filepath;
    }

    // None of the special cases matched, returning project_dir/file.
    return filepath;
}

// Find out the real name of an iOS or OSX project
// TODO: glob is slow, need a better way or caching, or avoid using more than once.
function getIOSProjectname (project_dir) {
    var matches = modules.glob.sync(path.join(project_dir, '*.xcodeproj'));
    var iospath;
    if (matches.length === 1) {
        iospath = path.basename(matches[0], '.xcodeproj');
    } else {
        var msg;
        if (matches.length === 0) {
            msg = 'Does not appear to be an xcode project, no xcode project file in ' + project_dir;
        } else {
            msg = 'There are multiple *.xcodeproj dirs in ' + project_dir;
        }
        throw new Error(msg);
    }
    return iospath;
}

// determine if a plist file is binary
function isBinaryPlist (filename) {
    // I wish there was a synchronous way to read only the first 6 bytes of a
    // file. This is wasteful :/
    var buf = '' + fs.readFileSync(filename, 'utf8');
    // binary plists start with a magic header, "bplist"
    return buf.substring(0, 6) === 'bplist';
}

module.exports = ConfigFile;
module.exports.isBinaryPlist = isBinaryPlist;
module.exports.getIOSProjectname = getIOSProjectname;
module.exports.resolveConfigFilePath = resolveConfigFilePath;
