// (C) Copyright 2020 Hewlett-Packard Enterprise Company, L.P.
define(['hp/services/Log', 'jquery'], function(log) {"use strict";

    var HelpModel = ( function() {

        var BASE_URL = '/help/',
            BASE_XML_OLD = BASE_URL + 'base.xml',
            TOPICS_XML = 'topics.xml';
            //DEFAULT_TOPIC_URI = "content";


        /**
         * @type {HelpModel}
         * @constructor
         */
        function HelpModel() {
            
            function replaceToken(message, token, value) {
                var text,
                    regex = new RegExp('{' + token + '}', "g");
                text = message.replace(regex, value);
                return text;
            }
            
            function replaceTokens(uri, substitutions) {
                var result = uri;
                $.each(substitutions, function (index, sub) {
                    result = replaceToken(result, sub.name, sub.value);
                });
                return result;
            }
            
            function getMapping(id, xml, lang) {
                var mapping;
                if (id) {
                    mapping = $("mapping[id='" + id + "']", xml).find('mapvalue').text();
                    log.info('Mapping ' + id + ' --> ' + (mapping ? mapping : ' Not Found'));
                }
                return mapping ? replaceTokens(mapping, [{name: 'locale', value: lang}]) : null;
            }
            
            function getTopicUri(help_id, xml, lang, defaultUri) {
                var topic_uri,
                    ids;
                
                if (help_id) {
                    ids = help_id.split('/');

                    while (!topic_uri  && (ids.length > 0)) {
                        topic_uri = getMapping(ids.join('\\/'), xml, lang);
                        ids.pop();
                    }
                }
                return topic_uri ? topic_uri : defaultUri;
            }

            function findLocation(context, group) {
               
                log.info('Loading ' + context.topics_uri);
                
                $.ajax({
                    type : "GET",
                    url : context.topics_uri,
                    dataType : "xml",
                    async : false,
                    success : function(xml) {
                        log.info('Got ' + context.topics_uri);
                        var topicUri = getTopicUri(context.help_id, xml, context.lang, context.default_uri),
                            finalUrl = context.base_content_url + (group ? group : '') + '/' + topicUri;
                        log.info('Choosing ' + finalUrl);
                        context.callback(finalUrl);
                    },
                    error : function() {
                        var finalUrl = context.base_content_url + '/' + context.default_uri;
                        log.info('Did not find topics.xml. Choosing ' + finalUrl);
                        context.callback(finalUrl);
                    }
                });
            }

            function getHelpContext(baseXml, group, help_id, lang, callback) {
                return {
                    base_content_url : getMapping('base', baseXml, lang),
                    default_uri : getMapping('default', baseXml, lang),
                    topics_uri : BASE_URL + group + (lang ? '/' + lang : '') + '/' + TOPICS_XML,
                    help_id : help_id,
                    lang : lang,
                    callback : callback
                };
            }
            
            /**
             * Look for the old style help base.xml and topics.xml files.
             *    /help/base.xml
             *    /help/<group>/topics.xml
             *       <topic> = lookup help_id in topics.xml.
             *    <base>/<group>/<topic>
             * @param group group (aka "book" of help content)
             * @param help_id A slash separated path of help. The first topic matching the most of the path is used.
             * @param callback The function to call with the final help URL.
             */
            function tryOldBase(group, help_id, callback) {
                log.info('Loading ' + BASE_XML_OLD);
                $.ajax({
                    type : "GET",
                    url : BASE_XML_OLD,
                    dataType : "xml",
                    async : false,
                    success : function(xml) {
                        var context = getHelpContext(xml, group, help_id, null, callback);
                        findLocation(context, group);
                    },
                    error : function() {
                        log.info('Did not find any base.xml');
                        callback(null);
                    }
                });
            }
            
            /**
             * Lookup for the help URL using base.xml and topics.xml files. These files should be in the form:
             *    /help/<group>/base.xml
             *    /help/<group>/<lang>/topics.xml
             *       <topic> = lookup help_id in topics.xml.
             *    <base>/<topic>
             * @param group group (aka "book" of help content)
             * @param help_id A slash separated path of help. The first topic matching the most of the path is used.
             * @param callback The function to call with the final help URL.
             */
            function findHelpUrl(group, help_id, lang, callback) {
                var baseUrl = BASE_URL + group + '/base.xml';
                
                log.info('Loading ' + baseUrl);
                
                $.ajax({
                    type : 'GET',
                    url : baseUrl,
                    dataType : 'xml',
                    async : false,
                    success : function(xml) {
                        var context = getHelpContext(xml, group, help_id, lang, callback);
                        log.info('Got ' + baseUrl + '. base=' + context.base_content_url + '  default=' + context.default_uri);
                        findLocation(context);
                    },
                    error : function() {
                        log.info('Did not find ' + baseUrl);
                        tryOldBase(group, help_id, callback);
                    }
                });
            }
            
            this.findHelpUrl = findHelpUrl;
            
            /**
             * Determine the help URL from the current hash and redirect to it.
             * @param lang The language to use.
             * @param callback The function to call with the final help URL.
             */
            this.help = function(lang, callback) {
                var group,
                    help_id,
                    hashparts = window.location.hash.substring(1).split('/');
                    group = hashparts[1];

                lang = lang ? lang : 'en';
                    
                if (hashparts.length >= 2) {
                    hashparts.shift();
                    hashparts.shift();
                    help_id = hashparts.join('/');
                }

                log.info('group=' + group);
                log.info('help_id=' + help_id);
                log.info('lang=' + lang);

                findHelpUrl(group, help_id, lang, callback);
            };
        }

        return new HelpModel();
    }());

    return HelpModel;
});
