﻿/*
 Licensed to the Apache Software Foundation (ASF) under one
 or more contributor license agreements.  See the NOTICE file
 distributed with this work for additional information
 regarding copyright ownership.  The ASF licenses this file
 to you 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.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SmartDevice.Connectivity;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Xml.XPath;
using System.Xml;
using System.Xml.Linq;


namespace CordovaDeploy
{

    class DeployTool
    {

        static void Usage()
        {
            Log("Usage: CordovaDeploy [ -devices  BuildOutputPath -d:DeviceIndex ]");
            Log("    -devices : lists the devices and exits");
            Log("    BuildOutputPath : path to the built application, typically Bin/Debug/ or Bin/Release/");
            Log("    -d : index of the device to deploy, default is 0 ");
            Log("examples:");
            Log("  CordovaDeploy -devices");
            Log("  CordovaDeploy Bin/Debug");
            Log("  CordovaDeploy Bin/Release -d:1");

        }

        static void ReadWait()
        {
            //Console.WriteLine("\nPress ENTER to continue...");
            //Console.Read();
        }

        static void Log(string msg)
        {
            Debug.WriteLine(msg);
            Console.Error.WriteLine(msg);
        }

        static Guid ReadAppId(string root)
        {
            Guid appID = Guid.Empty;
            string manifestFilePath = root + @"\Properties\WMAppManifest.xml";

            if (File.Exists(manifestFilePath))
            {
                XDocument xdoc = XDocument.Load(manifestFilePath);
                var appNode = xdoc.Root.Descendants("App").FirstOrDefault();
                if (appNode != null)
                {
                    string guidStr = appNode.Attribute("ProductID").Value;
                    appID = new Guid(guidStr);
                }
                else
                {
                    Log(string.Format("Unable to find appID, expected to find an App.ProductID property defined in the file {0}", manifestFilePath));
                }
            }
            else
            {
                Log(string.Format("Error: the file {0} does not exist", manifestFilePath));
            }


            return appID;
        }



        static void ListDevices()
        {
            // Get CoreCon WP7 SDK
            DatastoreManager dsmgrObj = new DatastoreManager(1033);
            Platform WP7SDK = dsmgrObj.GetPlatforms().Single(p => p.Name == "Windows Phone 7");
            Collection<Device> devices = WP7SDK.GetDevices();
            for (int index = 0; index < devices.Count; index++)
            {
                Device d = devices[index];
                string info = string.Format("{0} : {1} : {2}", index.ToString(), d.Id, d.Name);
                Log(info);
            }
        }

        static void Main(string[] args)
        {
            int deviceIndex = 0;

            string iconFilePath = "";
            string xapFilePath = "";
            Guid appID = Guid.Empty;

            string root = Directory.GetCurrentDirectory();

            if (args.Length < 1)
            {
                Usage();
                ReadWait();
                return;
            }
            else if (args[0] == "-devices")
            {
                ListDevices();
                return;
            }
            else if (args.Length > 1 && args[1].StartsWith("-d:"))
            {
                deviceIndex = int.Parse(args[1].Substring(3));
            }


            if (Directory.Exists(args[0]))
            {
                DirectoryInfo info = new DirectoryInfo(args[0]);
                root = info.FullName;
            }

            appID = ReadAppId(root);
            if (appID == Guid.Empty)
            {
                // Logging of errors is done in ReadAppId
                return;
            }

            if (File.Exists(root + @"\ApplicationIcon.png"))
            {
                iconFilePath = root + @"\ApplicationIcon.png";
            }
            else
            {
                Log(string.Format("Error: could not find application icon at {0}", root + @"\ApplicationIcon.png"));
                ReadWait();
                return;
            }


            xapFilePath = Directory.GetFiles(root + @"\Bin\Debug", "*.xap").FirstOrDefault();
            if (string.IsNullOrEmpty(xapFilePath))
            {
                Log(string.Format("Error: could not find application .xap in folder {0}", root));
                ReadWait();
                return;
            }


            // Get CoreCon WP7 SDK
            DatastoreManager dsmgrObj = new DatastoreManager(1033);
            Collection<Platform> WP7SDKs = dsmgrObj.GetPlatforms();
            Platform WP7SDK = dsmgrObj.GetPlatforms().Single(p => p.Name == "Windows Phone 7");

            Collection<Device> devices = null;

            devices = WP7SDK.GetDevices();

            //// Get Emulator / Device
            Device WP7Device = devices[deviceIndex];

            if (WP7Device != null)
            {
                RemoteApplication app;
                bool isConnected = WP7Device.IsConnected();

                Debug.WriteLine(WP7Device.ToString());

                if (!isConnected)
                {
                    try
                    {
                        WP7Device.Connect();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("Error: " + ex.Message);
                        ReadWait();
                        return;
                    }
                }

                if (WP7Device.IsApplicationInstalled(appID))
                {
                    Log("Uninstalling XAP from " + WP7Device.Name);
                    app = WP7Device.GetApplication(appID);
                    app.Uninstall();
                }

                Log("Installing app on " + WP7Device.Name);
                app = WP7Device.InstallApplication(appID, appID, "NormalApp", iconFilePath, xapFilePath);

                Log("Launching app on " + WP7Device.Name);
                app.Launch();

                ReadWait();
            }
        }
    }
}
