/*
** 2015 October 7
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C# code to download a single file based on a URI.
*/

using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;

///////////////////////////////////////////////////////////////////////////////

#region Assembly Metadata
[assembly: AssemblyTitle("GetFile Tool")]
[assembly: AssemblyDescription("Download a single file based on a URI.")]
[assembly: AssemblyCompany("SQLite Development Team")]
[assembly: AssemblyProduct("SQLite")]
[assembly: AssemblyCopyright("Public Domain")]
[assembly: ComVisible(false)]
[assembly: Guid("5c4b3728-1693-4a33-a218-8e6973ca15a6")]
[assembly: AssemblyVersion("1.0.*")]

#if DEBUG
[assembly: AssemblyConfiguration("Debug")]
#else
[assembly: AssemblyConfiguration("Release")]
#endif
#endregion

///////////////////////////////////////////////////////////////////////////////

namespace GetFile
{
    /// <summary>
    /// This enumeration is used to represent all the possible exit codes from
    /// this tool.
    /// </summary>
    internal enum ExitCode
    {
        /// <summary>
        /// The file download was a success.
        /// </summary>
        Success = 0,

        /// <summary>
        /// The command line arguments are missing (i.e. null).  Generally,
        /// this should not happen.
        /// </summary>
        MissingArgs = 1,

        /// <summary>
        /// The wrong number of command line arguments was supplied.
        /// </summary>
        WrongNumArgs = 2,

        /// <summary>
        /// The URI specified on the command line could not be parsed as a
        /// supported absolute URI.
        /// </summary>
        BadUri = 3,

        /// <summary>
        /// The file name portion of the URI specified on the command line
        /// could not be extracted from it.
        /// </summary>
        BadFileName = 4,

        /// <summary>
        /// The temporary directory is either invalid (i.e. null) or does not
        /// represent an available directory.
        /// </summary>
        BadTempPath = 5,

        /// <summary>
        /// An exception was caught in <see cref="Main" />.  Generally, this
        /// should not happen.
        /// </summary>
        Exception = 6,

        /// <summary>
        /// The file download was canceled.  This tool does not make use of
        /// the <see cref="WebClient.CancelAsync" /> method; therefore, this
        /// should not happen.
        /// </summary>
        DownloadCanceled = 7,

        /// <summary>
        /// The file download encountered an error.  Further information about
        /// this error should be displayed on the console.
        /// </summary>
        DownloadError = 8
    }

    ///////////////////////////////////////////////////////////////////////////

    internal static class Program
    {
        #region Private Data
        /// <summary>
        /// This is used to synchronize multithreaded access to the
        /// <see cref="previousPercent" /> and <see cref="exitCode"/>
        /// fields.
        /// </summary>
        private static readonly object syncRoot = new object();

        ///////////////////////////////////////////////////////////////////////

        /// <summary>
        /// This event will be signed when the file download has completed,
        /// even if the file download itself was canceled or unsuccessful.
        /// </summary>
        private static EventWaitHandle doneEvent;

        ///////////////////////////////////////////////////////////////////////

        /// <summary>
        /// The previous file download completion percentage seen by the
        /// <see cref="DownloadProgressChanged" /> event handler.  This value
        /// is never decreased, nor is it ever reset to zero.
        /// </summary>
        private static int previousPercent = 0;

        ///////////////////////////////////////////////////////////////////////

        /// <summary>
        /// This will be the exit code returned by this tool after the file
        /// download completes, successfully or otherwise.  This value is only
        /// changed by the <see cref="DownloadFileCompleted" /> event handler.
        /// </summary>
        private static ExitCode exitCode = ExitCode.Success;
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region Private Support Methods
        /// <summary>
        /// This method displays an error message to the console and/or
        /// displays the command line usage information for this tool.
        /// </summary>
        /// <param name="message">
        /// The error message to display, if any.
        /// </param>
        /// <param name="usage">
        /// Non-zero to display the command line usage information.
        /// </param>
        private static void Error(
            string message,
            bool usage
            )
        {
            if (message != null)
                Console.WriteLine(message);

            string fileName = Path.GetFileName(
                Process.GetCurrentProcess().MainModule.FileName);

            Console.WriteLine(String.Format("usage: {0} <uri>", fileName));
        }

        ///////////////////////////////////////////////////////////////////////

        /// <summary>
        /// This method attempts to determine the file name portion of the
        /// specified URI.
        /// </summary>
        /// <param name="uri">
        /// The URI to process.
        /// </param>
        /// <returns>
        /// The file name portion of the specified URI -OR- null if it cannot
        /// be determined.
        /// </returns>
        private static string GetFileName(
            Uri uri
            )
        {
            if (uri == null)
                return null;

            string pathAndQuery = uri.PathAndQuery;

            if (String.IsNullOrEmpty(pathAndQuery))
                return null;

            int index = pathAndQuery.LastIndexOf('/');

            if ((index < 0) || (index == pathAndQuery.Length))
                return null;

            return pathAndQuery.Substring(index + 1);
        }
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region Private Event Handlers
        /// <summary>
        /// This method is an event handler that is called when the file
        /// download completion percentage changes.  It will display progress
        /// on the console.  Special care is taken to make sure that progress
        /// events are not displayed out-of-order, even if duplicate and/or
        /// out-of-order events are received.
        /// </summary>
        /// <param name="sender">
        /// The source of the event.
        /// </param>
        /// <param name="e">
        /// Information for the event being processed.
        /// </param>
        private static void DownloadProgressChanged(
            object sender,
            DownloadProgressChangedEventArgs e
            )
        {
            if (e != null)
            {
                int percent = e.ProgressPercentage;

                lock (syncRoot)
                {
                    if (percent > previousPercent)
                    {
                        Console.Write('.');

                        if ((percent % 10) == 0)
                            Console.Write(" {0}% ", percent);

                        previousPercent = percent;
                    }
                }
            }
        }

        ///////////////////////////////////////////////////////////////////////

        /// <summary>
        /// This method is an event handler that is called when the file
        /// download has completed, successfully or otherwise.  It will
        /// display the overall result of the file download on the console,
        /// including any <see cref="Exception" /> information, if applicable.
        /// The <see cref="exitCode" /> field is changed by this method to
        /// indicate the overall result of the file download and the event
        /// within the <see cref="doneEvent" /> field will be signaled.
        /// </summary>
        /// <param name="sender">
        /// The source of the event.
        /// </param>
        /// <param name="e">
        /// Information for the event being processed.
        /// </param>
        private static void DownloadFileCompleted(
            object sender,
            AsyncCompletedEventArgs e
            )
        {
            if (e != null)
            {
                lock (syncRoot)
                {
                    if (previousPercent < 100)
                        Console.Write(' ');
                }

                if (e.Cancelled)
                {
                    Console.WriteLine("Canceled");

                    lock (syncRoot)
                    {
                        exitCode = ExitCode.DownloadCanceled;
                    }
                }
                else
                {
                    Exception error = e.Error;

                    if (error != null)
                    {
                        Console.WriteLine("Error: {0}", error);

                        lock (syncRoot)
                        {
                            exitCode = ExitCode.DownloadError;
                        }
                    }
                    else
                    {
                        Console.WriteLine("Done");
                    }
                }
            }

            if (doneEvent != null)
                doneEvent.Set();
        }
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region Program Entry Point
        /// <summary>
        /// This is the entry-point for this tool.  It handles processing the
        /// command line arguments, setting up the web client, downloading the
        /// file, and saving it to the file system.
        /// </summary>
        /// <param name="args">
        /// The command line arguments.
        /// </param>
        /// <returns>
        /// Zero upon success; non-zero on failure.  This will be one of the
        /// values from the <see cref="ExitCode" /> enumeration.
        /// </returns>
        private static int Main(
            string[] args
            )
        {
            //
            // NOTE: Sanity check the command line arguments.
            //
            if (args == null)
            {
                Error(null, true);
                return (int)ExitCode.MissingArgs;
            }

            if (args.Length != 1)
            {
                Error(null, true);
                return (int)ExitCode.WrongNumArgs;
            }

            //
            // NOTE: Attempt to convert the first (and only) command line
            //       argument to an absolute URI.
            //
            Uri uri;

            if (!Uri.TryCreate(args[0], UriKind.Absolute, out uri))
            {
                Error("Could not create absolute URI from argument.", false);
                return (int)ExitCode.BadUri;
            }

            //
            // NOTE: Attempt to extract the file name portion of the URI we
            //       just created.
            //
            string fileName = GetFileName(uri);

            if (fileName == null)
            {
                Error("Could not extract the file name from the URI.", false);
                return (int)ExitCode.BadFileName;
            }

            //
            // NOTE: Grab the temporary path setup for this process.  If it is
            //       unavailable, we will not continue.
            //
            string directory = Path.GetTempPath();

            if (String.IsNullOrEmpty(directory) ||
                !Directory.Exists(directory))
            {
                Error("Temporary directory is invalid or unavailable.", false);
                return (int)ExitCode.BadTempPath;
            }

            try
            {
                using (WebClient webClient = new WebClient())
                {
                    //
                    // NOTE: Create the event used to signal completion of the
                    //       file download.
                    //
                    doneEvent = new ManualResetEvent(false);

                    //
                    // NOTE: Hookup the event handlers we care about on the web
                    //       client.  These are necessary because the file is
                    //       downloaded asynchronously.
                    //
                    webClient.DownloadProgressChanged +=
                        new DownloadProgressChangedEventHandler(
                            DownloadProgressChanged);

                    webClient.DownloadFileCompleted +=
                        new AsyncCompletedEventHandler(
                            DownloadFileCompleted);

                    //
                    // NOTE: Build the fully qualified path and file name,
                    //       within the temporary directory, where the file to
                    //       be downloaded will be saved.
                    //
                    fileName = Path.Combine(directory, fileName);

                    //
                    // NOTE: If the file name already exists (in the temporary)
                    //       directory, delete it.
                    //
                    // TODO: Perhaps an error should be raised here instead?
                    //
                    if (File.Exists(fileName))
                        File.Delete(fileName);

                    //
                    // NOTE: After kicking off the asynchronous file download
                    //       process, wait [forever] until the "done" event is
                    //       signaled.
                    //
                    Console.WriteLine(
                        "Downloading \"{0}\" to \"{1}\"...", uri, fileName);

                    webClient.DownloadFileAsync(uri, fileName);
                    doneEvent.WaitOne();
                }

                lock (syncRoot)
                {
                    return (int)exitCode;
                }
            }
            catch (Exception e)
            {
                //
                // NOTE: An exception was caught.  Report it via the console
                //       and return failure.
                //
                Error(e.ToString(), false);
                return (int)ExitCode.Exception;
            }
        }
        #endregion
    }
}
