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

using Microsoft.Phone.Controls;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.IsolatedStorage;
using System.Linq;
using System.Text;
using System.Windows;

namespace WPCordovaClassLib.CordovaLib
{
    public class XHRHelper : IBrowserDecorator
    {

        public WebBrowser Browser { get; set; }
        public PhoneApplicationPage Page { get; set; }

        public void InjectScript()
        {
            string script = @"(function(win, doc) {

    var __XHRShimAliases = {};

    window.__onXHRLocalCallback = function (responseCode, responseText, reqId) {
        if (__XHRShimAliases[reqId]){
            var alias = __XHRShimAliases[reqId];
            if (alias){
                delete __XHRShimAliases[reqId];
                if (responseCode == '200'){
                    alias.onResult && alias.onResult(responseText);
                    Object.defineProperty(alias, 'responseXML', {
                        get: function () {
                            return new DOMParser().parseFromString(this.responseText, 'text/xml');
                        }
                    });
                } else {
                    alias.onError && alias.onError(responseText);
                }
            }
        }
    };

    var docDomain = null;
    try {
        docDomain = doc.domain;
    } catch (err) {}

    if (!docDomain || docDomain.length === 0) {

        var aliasXHR = win.XMLHttpRequest;

        var XHRShim = function() {};
        win.XMLHttpRequest = XHRShim;
        XHRShim.noConflict = aliasXHR;
        XHRShim.UNSENT = 0;
        XHRShim.OPENED = 1;
        XHRShim.HEADERS_RECEIVED = 2;
        XHRShim.LOADING = 3;
        XHRShim.DONE = 4;
        XHRShim.prototype = {
            isAsync: false,
            onreadystatechange: null,
            readyState: 0,
            _url: '',
            timeout: 0,
            withCredentials: false,
            _requestHeaders: null,
            open: function (reqType, uri, isAsync, user, password) {

                if (uri && uri.indexOf('http') === 0) {
                    if (!this.wrappedXHR) {
                        this.wrappedXHR = new aliasXHR();
                        var self = this;
                        if (this.timeout > 0) {
                            this.wrappedXHR.timeout = this.timeout;
                        }
                        Object.defineProperty(this, 'timeout', {
                            set: function(val) {
                                this.wrappedXHR.timeout = val;
                            },
                            get: function() {
                                return this.wrappedXHR.timeout;
                            }
                        });
                        if (this.withCredentials) {
                            this.wrappedXHR.withCredentials = this.withCredentials;
                        }
                        Object.defineProperty(this, 'withCredentials', {
                            set: function(val) {
                                this.wrappedXHR.withCredentials = val;
                            },
                            get: function() {
                                return this.wrappedXHR.withCredentials;
                            }
                        });
                        Object.defineProperty(this, 'status', {
                            get: function() {
                                return this.wrappedXHR.status;
                            }
                        });
                        Object.defineProperty(this, 'responseText', {
                            get: function() {
                                return this.wrappedXHR.responseText;
                            }
                        });
                        Object.defineProperty(this, 'statusText', {
                            get: function() {
                                return this.wrappedXHR.statusText;
                            }
                        });
                        Object.defineProperty(this, 'responseXML', {
                            get: function() {
                                return this.wrappedXHR.responseXML;
                            }
                        });
                        Object.defineProperty(this, 'response', {
                            get: function() {
                                return this.wrappedXHR.response;
                            }
                        });
                        Object.defineProperty(this, 'responseType', {
                            set: function(val) {
                                return this.wrappedXHR.responseType = val;
                            }
                        });
                        this.getResponseHeader = function(header) {
                            return this.wrappedXHR.getResponseHeader(header);
                        };
                        this.getAllResponseHeaders = function() {
                            return this.wrappedXHR.getAllResponseHeaders();
                        };
                        this.wrappedXHR.onreadystatechange = function() {
                            self.changeReadyState(self.wrappedXHR.readyState);
                        };
                    }
                    return this.wrappedXHR.open(reqType, uri, isAsync, user, password);
                }
                else
                {
                    this.isAsync = isAsync;
                    this.reqType = reqType;
                    this._url = uri;
                }
            },
            statusText: '',
            changeReadyState: function(newState) {
                this.readyState = newState;
                if (this.onreadystatechange) {
                    // mimic simple 'readystatechange' event which should be passed as per spec
                    var evt = {type: 'readystatechange', target: this, timeStamp: new Date().getTime()};
                    this.onreadystatechange(evt);
                }
                if (this.readyState == XHRShim.DONE){
                    this.onload && this.onload();
                }
            },
            addEventListener: function (type, listener, useCapture){
                if (this.wrappedXHR) {
                    this.wrappedXHR.addEventListener(type, listener, useCapture);
                } else {
                    this['on' + type] = listener;
                }
            },
            removeEventListener: function (type, listener, useCapture){
                if (this.wrappedXHR) {
                    this.wrappedXHR.removeEventListener(type, listener, useCapture);
                } else {
                    if (this['on' + type] == listener) { // if listener is currently used
                        delete this['on' + type];
                    }
                }
            },
            setRequestHeader: function(header, value) {
                if (this.wrappedXHR) {
                    this.wrappedXHR.setRequestHeader(header, value);
                }
            },
            getResponseHeader: function(header) {
                return this.wrappedXHR ? this.wrappedXHR.getResponseHeader(header) : '';
            },
            getAllResponseHeaders: function() {
                return this.wrappedXHR ? this.wrappedXHR.getAllResponseHeaders() : '';
            },
            overrideMimeType: function(mimetype) {
                return this.wrappedXHR ? this.wrappedXHR.overrideMimeType(mimetype) : '';
            },
            responseText: '',
            responseXML: '',
            onResult: function(res) {
                this.status = 200;
                if (typeof res == 'object') {
                    res = JSON.stringify(res);
                }
                this.responseText = res;
                this.responseXML = res;
                this.changeReadyState(XHRShim.DONE);
            },
            onError: function(err) {
                this.status = 404;
                this.changeReadyState(XHRShim.DONE);
            },
            abort: function() {
                if (this.wrappedXHR) {
                    return this.wrappedXHR.abort();
                }
            },
            send: function(data) {
                if (this.wrappedXHR) {
                    return this.wrappedXHR.send(data);
                }
                else {
                    this.changeReadyState(XHRShim.OPENED);
                    var alias = this;

                    var root = window.location.href.split('#')[0];   // remove hash
                    
                    var rootPath = root.substr(0,root.lastIndexOf('/')) + '/';
                    // Removing unwanted slashes after x-wmapp0 from the basePath, URI cannot process x-wmapp0: /www or //www
                    var basePath = rootPath.replace(/:\/+/gi, ':');

                    //console.log( 'Stripping protocol if present and removing leading / characters' );
                    var resolvedUrl =
                            // remove protocol from the beginning of the url if present
                            ( this._url.indexOf( window.location.protocol ) === 0 ?
                                this._url.substring( window.location.protocol.length ) :
                                this._url )
                            // get rid of all the starting slashes
                            .replace(/^[/]*/, '')
                            .split('#')[0]; // remove hash

                    var wwwFolderPath = navigator.userAgent.indexOf('MSIE 9.0') > -1 ? 'app/www/' : 'www/';

                    // handle special case where url is of form app/www but we are loaded just from /www
                    if( resolvedUrl.indexOf('app/www') == 0 ) {
                        resolvedUrl = window.location.protocol  + wwwFolderPath + resolvedUrl.substr(7);
                    }
                    else if( resolvedUrl.indexOf('www') == 0) {
                        resolvedUrl = window.location.protocol  + wwwFolderPath + resolvedUrl.substr(4);
                    }

                    if(resolvedUrl.indexOf(':') < 0) {
                        resolvedUrl = basePath + resolvedUrl; // consider it relative
                    }

                    // Generate unique request ID
                    var reqId = new Date().getTime().toString() + Math.random();

                    var funk = function () {
                        __XHRShimAliases[reqId] = alias;

                        alias.changeReadyState(XHRShim.LOADING);
                        window.external.Notify('XHRLOCAL/' + reqId + '/' + resolvedUrl);
                    };

                    this.isAsync ? setTimeout(funk, 0) : funk();
                }
            },
            status: 404
        };
    }
})(window, document); ";


            Browser.InvokeScript("eval", new string[] { script });
        }

        public bool HandleCommand(string commandStr)
        {
            if (commandStr.IndexOf("XHRLOCAL") == 0)
            {
                var reqStr = commandStr.Replace("XHRLOCAL/", "").Split(new char[] {'/'}, 2);
                string reqId = reqStr[0];
                string url = reqStr[1];

                Uri uri = new Uri(url, UriKind.RelativeOrAbsolute);
                try
                {
                    using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
                    {
                        if (isoFile.FileExists(uri.AbsolutePath))
                        {
                            using (TextReader reader = new StreamReader(isoFile.OpenFile(uri.AbsolutePath, FileMode.Open, FileAccess.Read)))
                            {
                                string text = reader.ReadToEnd();
                                Browser.InvokeScript("__onXHRLocalCallback", new string[] { "200", text, reqId });
                                return true;
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    Debug.WriteLine("ERROR: Exception in HandleCommand: " + ex);
                }

                Uri relUri = new Uri(uri.AbsolutePath, UriKind.Relative);

                var resource = Application.GetResourceStream(relUri);
                try
                {
                    if (resource == null)
                    {
                        // 404 ?
                        Browser.InvokeScript("__onXHRLocalCallback", new string[] { "404", null, reqId });
                        return true;
                    }
                    else
                    {
                        using (StreamReader streamReader = new StreamReader(resource.Stream))
                        {
                            string text = streamReader.ReadToEnd();
                            Browser.InvokeScript("__onXHRLocalCallback", new string[] { "200", text, reqId });
                            return true;
                        }
                    }
                }
                catch (Exception ex)
                {
                    Debug.WriteLine("ERROR: Exception in HandleCommand: " + ex);
                }
            }

            return false;
        }
    }
}
