/*
	Licensed Material - Property of IBM

	(C) Copyright 2015,2016 IBM Corp.

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


'use strict';

var et = require('elementtree');
var fs = require('fs');
var log = require('npmlog');
var glob = require('glob');
var path = require('path');
var q = require('q');
var readClientProperties = require('./process-properties-file/readClientProperties');

/**
    Tries to find metadata out of existing Native Client Project
    @param rootDir: the root directory of where the .appxmanifest file exists
    @returns metadata
    {
        'app.version': '1.0.0',
        'app.displayname': 'BlueList',
        'app.id': 'com_ibm_BlueList',
        'app.description': 'com_ibm_BlueList'
    }
*/
module.exports = function (rootDir){
    var d = q.defer();

    var clientMetadata = {};
    var data, etree;

    clientMetadata['app.version'] = "";
    clientMetadata['app.name'] = "";
    clientMetadata['app.dotId'] = "";

    try{
        var appxmanifest = glob.sync('**/package.appxmanifest', {cwd: rootDir, nocase: true});
        if(appxmanifest.length !== 0) {
            var appxmanifestPath = path.resolve(rootDir, appxmanifest[0]);
            data = fs.readFileSync(appxmanifestPath, {encoding:'utf8'}).toString();
            //To clear BOM marker
            var cleanedString = data.replace("\ufeff", "");
            etree = et.parse(cleanedString);
            //Assign to clientMetadata the path that we used to read the appxmanifest
            clientMetadata.appxmanifestPath = appxmanifestPath;

            //Determine if it is a Windows10 app
            var targetDevice = etree.find('./Dependencies/TargetDeviceFamily');
            if(targetDevice) {
                var windowsVersion = targetDevice.attrib.MinVersion;
                windowsVersion = windowsVersion.substr(0, windowsVersion.indexOf('.'));
                clientMetadata['isWindows10'] = windowsVersion >= 10;
            } else {
                clientMetadata['isWindows10'] = false;
            }

            //Determine if Package.appxmanifest has Phone Property
            var phoneIdentity = etree.find('./mp:PhoneIdentity');
            if(phoneIdentity) {
              clientMetadata['hasPhoneIdentity'] = true;
            } else {
              clientMetadata['hasPhoneIdentity'] = false;
            }

            //Get the version
            var identityElement = etree.find('./Identity');
            var version = identityElement.get('Version');
            if(!version) {
              version = '';
            }
            clientMetadata['app.version'] = version;

            var displayElement = etree.find('./Properties/DisplayName');
            clientMetadata['app.name'] = displayElement.text;
            //Windows projects have multiple appxmanifest files, name can be ProjectName.Windows or ProjectName.WindowsPhone, so we need to strip off that suffix
            if(path.extname(clientMetadata['app.name']).indexOf('Windows') > 0) {
                var appNameSplit = clientMetadata['app.name'].split('.');
                appNameSplit.pop(appNameSplit.length - 1);
                var appName = '';
                for(var i = 0, appNameLength = appNameSplit.length; i < appNameLength; i++) {
                    if(appName !== '') {
                        appName += '.';
                    }
                    appName += appNameSplit[i];
                }
                clientMetadata['app.name'] = appName;
            }
            // Native windows applications cannot contain spaces when calling app register
            clientMetadata['app.dotId'] = displayElement.text.replace(/\s+/g, '.');
            // Remove .Windows and .WindowsPhone from appId
            if (clientMetadata['app.dotId'].lastIndexOf('.Windows') > -1) {
                clientMetadata['app.dotId'] = clientMetadata['app.dotId'].slice(0, clientMetadata['app.dotId'].lastIndexOf('.Windows'));
            }

            // If mfpclient.resw exists, make wlAppId the same as assemblyName
            var resw = glob.sync('**/mfpclient.resw', {cwd: rootDir, nocase: true});
            if (resw[0]) {
                var mfpClientPath = path.dirname(path.resolve(rootDir, resw[0]));

                try {
                    fs.statSync(mfpClientPath);
                } catch(err) {
                    log.verbose('parseNativeWindows', 'strings folder did not exist, creating it now');
                    fs.mkdirSync(mfpClientPath);
                }
                // Copy app.dotId to mfpclient.resw so that wlAppId is the same as assemblyName and DisplayName - fix for APAR 105528
                readClientProperties(mfpClientPath, 'mfpclient.resw')
                .then(function (reswObj) {		//Success call, has contents of mfpclient.properties
                        return reswObj;
                    }, function (err) {		//Error: log error message
                        log.error(err);
                })
                .then(function (reswObj) {
                    reswObj.setDataEntry('wlAppId', clientMetadata['app.dotId']);
                    reswObj.writeFile(path.resolve(mfpClientPath, 'mfpclient.resw'));
                    d.resolve();
                })
                .catch(function (err) {
                    d.reject(err);
                });
            }

            d.resolve(clientMetadata);
        } else {
            throw new Error('package.appxmanifest not found');
        }
    } catch (err) {
        log.silly('error parsing packageappxmanifest' + err.message);
        d.reject();
    }

    return d.promise;
};
