﻿/*  
	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 System;
using System.Diagnostics;
using System.Threading;
using Microsoft.Devices;
using Microsoft.Phone.Controls;
using WPCordovaClassLib.Cordova.Commands;
using System.Windows;

namespace WPCordovaClassLib.Cordova
{
    /// <summary>
    /// Implements logic to execute native command and return result back.
    /// All commands are executed asynchronous.
    /// </summary>
    public class NativeExecution
    {
        /// <summary>
        /// Reference to web part where application is hosted
        /// </summary>
        private readonly WebBrowser webBrowser;

        /// <summary>
        /// Creates new instance of a NativeExecution class. 
        /// </summary>
        /// <param name="browser">Reference to web part where application is hosted</param>
        public NativeExecution(ref WebBrowser browser)
        {
            if (browser == null)
            {
                throw new ArgumentNullException("browser");
            }

            this.webBrowser = browser;
        }

        /// <summary>
        /// Returns where application is running on emulator
        /// </summary>
        /// <returns>True if running on emulator, otherwise False</returns>
        public static bool IsRunningOnEmulator()
        {
            return Microsoft.Devices.Environment.DeviceType == DeviceType.Emulator;
        }

        public void ResetAllCommands()
        {
            CommandFactory.ResetAllCommands();
        }

        /// <summary>
        /// Executes command and returns result back.
        /// </summary>
        /// <param name="commandCallParams">Command to execute</param>
        
        public void ProcessCommand(CordovaCommandCall commandCallParams)
        {

            
            if (commandCallParams == null)
            {
                throw new ArgumentNullException("commandCallParams");
            }

            try
            {
                BaseCommand bc = CommandFactory.CreateByServiceName(commandCallParams.Service);

                if (bc == null)
                {
                    this.OnCommandResult(commandCallParams.CallbackId, new PluginResult(PluginResult.Status.CLASS_NOT_FOUND_EXCEPTION));
                    return;
                }

                EventHandler<PluginResult> OnCommandResultHandler = delegate(object o, PluginResult res)
                {
                    this.OnCommandResult(commandCallParams.CallbackId, res);
                };

                bc.OnCommandResult -= OnCommandResultHandler;
                bc.OnCommandResult += OnCommandResultHandler;

                EventHandler<ScriptCallback> OnCustomScriptHandler = delegate(object o, ScriptCallback script)
                {
                    this.InvokeScriptCallback(script);
                };

                bc.OnCustomScript -= OnCustomScriptHandler;
                bc.OnCustomScript += OnCustomScriptHandler;

                // TODO: alternative way is using thread pool (ThreadPool.QueueUserWorkItem) instead of 
                // new thread for every command call; but num threads are not sufficient - 2 threads per CPU core

                Thread thread = new Thread(func =>
                {
                    try
                    {
                        bc.InvokeMethodNamed(commandCallParams.Action, commandCallParams.Args);
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine("ERROR: Exception in ProcessCommand :: " + ex.Message);
                        bc.OnCommandResult -= OnCommandResultHandler;
                        bc.OnCustomScript -= OnCustomScriptHandler;

                        Debug.WriteLine("ERROR: failed to InvokeMethodNamed :: " + commandCallParams.Action + " on Object :: " + commandCallParams.Service);

                        this.OnCommandResult(commandCallParams.CallbackId, new PluginResult(PluginResult.Status.INVALID_ACTION));

                        return;
                    }
                });

                thread.Start();
            }
            catch (Exception ex)
            {
                // ERROR
                Debug.WriteLine(String.Format("ERROR: Unable to execute command :: {0}:{1}:{3} ",
                    commandCallParams.Service, commandCallParams.Action, ex.Message));

                this.OnCommandResult(commandCallParams.CallbackId, new PluginResult(PluginResult.Status.ERROR));
                return;
            }
        }

        /// <summary>
        /// Handles command execution result.
        /// </summary>
        /// <param name="callbackId">Command callback identifier on client side</param>
        /// <param name="result">Execution result</param>
        private void OnCommandResult(string callbackId, PluginResult result)
        {
            #region  args checking

            if (result == null)
            {
                Debug.WriteLine("ERROR: OnCommandResult missing result argument");
                return;
            }

            if (String.IsNullOrEmpty(callbackId))
            {
                Debug.WriteLine("ERROR: OnCommandResult missing callbackId argument");
                return;
            }

            #endregion

            string status = ((int)result.Result).ToString();
            string jsonResult = result.ToJSONString();

            ScriptCallback scriptCallback = null;

            if (String.IsNullOrEmpty(result.Cast))
            {
                scriptCallback = new ScriptCallback("CordovaCommandResult", new string[] { status, callbackId, jsonResult });
            }
            else
            {
                scriptCallback = new ScriptCallback("CordovaCommandResult", new string[] { status, callbackId, jsonResult, result.Cast });
            }

            this.InvokeScriptCallback(scriptCallback);

        }

        /// <summary>
        /// Executes client java script
        /// </summary>
        /// <param name="script">Script to execute on client side</param>
        private void InvokeScriptCallback(ScriptCallback script)
        {
            if (script == null)
            {
                throw new ArgumentNullException("script");
            }

            if (String.IsNullOrEmpty(script.ScriptName))
            {
                throw new ArgumentNullException("ScriptName");
            }

            //Debug.WriteLine("INFO:: About to invoke ::" + script.ScriptName + " with args ::" + script.Args[0]);
            this.webBrowser.Dispatcher.BeginInvoke((ThreadStart)delegate()
            {

                try
                {
                    //Debug.WriteLine("INFO:: InvokingScript::" + script.ScriptName + " with args ::" + script.Args[0]);
                    this.webBrowser.InvokeScript(script.ScriptName, script.Args);
                }
                catch (Exception ex)
                {
                    Debug.WriteLine("ERROR: Exception in InvokeScriptCallback :: " + ex.Message);
                }

            });
        }

    }
}