using Ionic.Zip;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls; 

public partial class app_custom_screens_IHConfiguration_upload_update_api : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        bool failed = false; string json = ""; 
        HttpFileCollection fileCollection = Request.Files;
        if (fileCollection.Count > 0)
        {
            HttpPostedFile file = fileCollection[0];
            string path = ConfigurationManager.AppSettings.Get("ihboxUpdatesFolder");
            string zipPassword = ConfigurationManager.AppSettings.Get("ihboxUpdatesPassword");

            if (path != null)
            {
                Guid g = Guid.NewGuid();
                string filename = Path.Combine(path, g.ToString() + ".zip");
                file.SaveAs(filename);

                bool success = false; 
                string unzipPath = Unzip(g.ToString(), path, filename, zipPassword, out success);

                if (success)
                {
                    success = this.ExecuteUpdateFile(unzipPath);
                }
                else
                {
                    try
                    {
                        File.Delete(filename);
                    }
                    catch (Exception ex)
                    {
                    }
                }

                if (success)
                {
                    json = "{\"status\":\"OK\"}";
                    Response.Clear();
                    Response.ContentType = "application/json; charset=utf-8";
                    Response.Write(json);
                    Response.End();
                }

                failed = !success; 
            }
            else
            {
                failed = true; 
            }
        }
        else
        {
            failed = true; 
        }

        if (failed)
        {
            json = "{\"status\":\"FAILED\"}";
            Response.Clear();
            Response.ContentType = "application/json; charset=utf-8";
            Response.Write(json);
            Response.End();
        }
    }

    public bool ExecuteUpdateFile(string path)
    {
        bool result = false;

        DirectoryInfo dinfo = new DirectoryInfo(path);
        foreach (FileInfo fi in dinfo.GetFiles("setup.*"))
        {
            switch (fi.Extension.ToUpper())
            {
                case ".BAT":
                    return ExecuteBatFile(fi);
                case ".EXE":
                    return ExecuteExeFile(fi); 
            }
        }

        return result; 
    }

    public bool ExecuteBatFile(FileInfo fi)
    {
        bool result = false; 
        try
        {
            string enginePath = fi.FullName;
            result = ExecuteCommandOnServerFromBat(fi.DirectoryName, fi.FullName); 
        }
        catch (Exception ex)
        {
            result = false; 
        }

        return result;
    }

    public bool ExecuteExeFile(FileInfo fi)
    {
        bool result = false;
        try
        {
            string enginePath = fi.FullName;
            System.Diagnostics.ProcessStartInfo info = new System.Diagnostics.ProcessStartInfo(enginePath, "");
            System.Diagnostics.Process p = System.Diagnostics.Process.Start(info);
            p.WaitForExit(); 

            result = true;
        }
        catch (Exception ex)
        {
            result = false;
        }

        return result;
    }

    private bool ExecuteCommandOnServerFromBat(string workingDirectory, string pathToBat)
    {
        bool ret = false;
        try
        {
            // Create the ProcessInfo object
            System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo("cmd.exe");
            psi.UseShellExecute = false;
            psi.RedirectStandardOutput = true;
            psi.RedirectStandardInput = true;
            psi.RedirectStandardError = true;
            psi.WorkingDirectory = workingDirectory;

            //string usernameString = "Administrator"; 
            //string PwString = "AustralTek2012";
            //string domain = null; 
            //char[] PasswordChars = PwString.ToCharArray();
            //System.Security.SecureString passwordString = new System.Security.SecureString();
            //foreach (char c in PasswordChars)
            //    passwordString.AppendChar(c);

            //psi.UserName = usernameString;
            //psi.Password = passwordString; 

            // Start the process
            System.Diagnostics.Process proc = System.Diagnostics.Process.Start(psi);
            // Open the batch file for reading
            System.IO.StreamReader strm = System.IO.File.OpenText(pathToBat);
            // Attach the output for reading
            System.IO.StreamReader sOut = proc.StandardOutput;
            // Attach the in for writing
            System.IO.StreamWriter sIn = proc.StandardInput;
            // Write each line of the batch file to standard input

            while (strm.Peek() != -1)
            {
                sIn.WriteLine(strm.ReadLine());
            }
            strm.Close();
            // Exit CMD.EXE
            sIn.WriteLine("EXIT");
            // Close the process
            proc.Close();
            // Read the sOut to a string.
            string results = sOut.ReadToEnd().Trim();
            // Close the io Streams;
            sIn.Close();
            sOut.Close();
            ret = true;
        }
        catch (Exception ex)
        {
            ret = false;
        }
        return ret;
    }

    public string Unzip(string filename, string dir, string path, string password, out bool success)
    {
        success = false; 
        try
        {
            string extractDir = Path.Combine(dir, filename + "-extracted");

            using (ZipFile zip1 = ZipFile.Read(path))
            {
                foreach (ZipEntry e in zip1)
                {
                    if (e.UsesEncryption == true)
                    {
                        e.ExtractWithPassword(extractDir, ExtractExistingFileAction.OverwriteSilently, password);
                        success = true; 
                    }
                }
            }

            return extractDir; 
        }
        catch (Exception ex)
        {
            success = false; 
            return null; 
        }
    }
}