using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace isn
{
    public class PushCommand
    {
        static public async Task<PushReport> RunAsync(string pkg, string source, string apikey)
        {
            FileInfo fi = new FileInfo(pkg);
            var report = new PushReport
            {
                PkgName = fi.Name
            };
            if (!fi.Exists)
            {
                report.Message = "Le fichier n'existe pas";
                return report;
            }

            try
            {
                var wrqueryHandler = new UploadFilesToServerUsingWebRequest();
                // await wrqueryHandler.UploadFilesToServerAsync(report, new Uri(source), fi, apikey);
                if (source == null) 
                {
                    source = Program.Settings.DefaultSource;
                    if (apikey is null)  if (source!=null)
                    apikey = Program.Protector.UnProtect(Program.Settings.Sources[source].ApiKey);
                }
                if (apikey is null) if (source!=null)
                if (Program.Settings.Sources.ContainsKey(source))
                apikey = Program.Protector.UnProtect(Program.Settings.Sources[source].ApiKey);
                if (source == null) throw new InvalidOperationException("source is null");
                var resources = await SourceHelpers.GetServerResourcesAsync(source);
                if (resources.Resources==null || resources.Resources.Any(res => res.Id == "" ))
                throw new InvalidOperationException("Source won't serve the expected push command");
                Console.WriteLine(JsonConvert.SerializeObject(resources));
                wrqueryHandler.UploadFilesToServer(report, new Uri(resources.Resources[0].Id), fi, apikey);
            }
            catch (WebException ex)
            {
                await Console.Error.WriteLineAsync(ex.Message);
                report.StatusCode = ex.Status.ToString();
                report.OK = false;
                using (Stream respStream = ex.Response.GetResponseStream())
                {
                    StreamReader sr = new StreamReader(respStream);
                    string json = sr.ReadToEnd();
                    var res = JsonConvert.DeserializeObject<IsndErrorMessage>(json);
                    // ecode == 1 => package already present server side.
                    report.AlreadyPresent = res.ecode == 1;
                    report.Message = res.msg;
                }
            }
            catch (Exception ex)
            {
                report.Message = ex.Message;
                report.StackTrace = ex.StackTrace;
                await Console.Error.WriteLineAsync(ex.Message);
                throw;
            }
            report.Executed = true;
            return report;
        }
    }
}