//  
//   Rebex Sample Code License
// 
//   Copyright 2026, REBEX CR s.r.o.
//   All rights reserved.
//   https://www.rebex.net/
// 
//   Permission to use, copy, modify, and/or distribute this software for any
//   purpose with or without fee is hereby granted.
// 
//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
//   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
//   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
//   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
//   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
//   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
//   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
//   OTHER DEALINGS IN THE SOFTWARE.
// 

using System;
using System.Threading.Tasks;
using Rebex.Net;

namespace Rebex.Samples
{
    /// <summary>
    /// Simple but very fast HTTP/HTTPS downloader.
    /// Uses Rebex TLS library to provide TLS 1.3 and 1.2 layer: https://www.rebex.net/tls/
    /// 
    /// This is a sample code that only implements HTTP partially and is not suitable for general use.
    /// Consider using Rebex HTTPS library in such scenarios: https://www.rebex.net/https/
    /// </summary>
    public class Program
    {
        // Error returned when the command line is not syntactically valid.
        private const int PARSE_OPTIONS_ERROR = -1;

        // Error returned when a TLS error occurs.
        private const int TLS_ERROR = -2;

        // Error returned when a fatal error occurs.
        private const int GENERAL_ERROR = -1001;

        // Error message which is shown when a general error occurs.
        private const string SAMPLE_LIMITS_MESSAGE =
            "**************************************************************************************************\n" +
            "An error occured. This application is a sample that demonstrates the use and performance\n" +
            "of Rebex TlsStream class. It only features basic support for the HTTP protocol.\n" +
            "\n" +
            "For more advanced scenarios, consider using the robust and battle-tested Rebex HTTPS component\n" +
            "instead: https://www.rebex.net/https/ \n" +
            "**************************************************************************************************\n";

        /// <summary>
        /// Asynchronous application entry point.
        /// </summary>
        /// <returns>
        /// A Task that represent the asynchronous operation.
        /// Exit code 0 indicates success. Other results indicate error.
        /// </returns>
        static async Task<int> Main(string[] args)
        {
            // set the trial license key
            Rebex.Licensing.Key = Rebex.Samples.TrialKey.Key;


            bool quietMode = false;
            try
            {
                // Parse command line options.
                var options = HttpDownloaderOptions.CreateFrom(args);

                // If options could not be parsed or the user did not provide an URL, display usage info and exit.
                if (options == null || (string.IsNullOrEmpty(options.Url) && string.IsNullOrEmpty(options.InputFileWithUrlsPath)))
                {
                    Console.WriteLine(HttpDownloaderOptions.APP_USAGE);
                    return PARSE_OPTIONS_ERROR;
                }

                // If -h option (help) was specified, display usage info and exit.
                if (options.ShowHelp)
                {
                    Console.WriteLine(HttpDownloaderOptions.APP_USAGE);
                    return 0;
                }

                // If -q (quiet mode) option was specified, turn off logging.
                quietMode = options.QuietMode;

                // Create an instance of HttpDownloader class and download specified URLs
                var downloader = new HttpDownloader();
                return await downloader.DownloadUrls(options).ConfigureAwait(false);
            }
            catch (OptionsParserException ex)
            {
                // If command line options parser failed, show the error and exit with PARSE_OPTIONS_ERROR error code.
                if (!quietMode)
                {
                    Console.WriteLine(ex);
                    Console.WriteLine();
                    Console.WriteLine(HttpDownloaderOptions.APP_USAGE);
                }
                return PARSE_OPTIONS_ERROR;
            }
            catch (TlsException ex)
            {
                // If the application failed due to a TLS error, show the error and exit with TLS_ERROR error code.
                if (!quietMode)
                {
                    Console.WriteLine(ex);
                }
                return TLS_ERROR;
            }
            catch (Exception ex)
            {
                // If the application failed, show the error and exit with GENERAL_ERROR error code.
                // IMPORTANT: For applications to be used in production, use more robust error handling.
                if (!quietMode)
                {
                    Console.WriteLine(SAMPLE_LIMITS_MESSAGE);
                    Console.WriteLine();
                    Console.WriteLine(ex);
                }
                return GENERAL_ERROR;
            }
        }
    }
}
