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 PushReport Run(string pkg, string source)
        {
            if (source == null) source = Program.Settings.DefaultSource;
            if (source == null) throw new InvalidOperationException("source is null");
            string apikey = Program.Protector.UnProtect(Program.Settings.Sources[source].ApiKey);
            var resources =  SourceHelpers.GetServerResources(source);
            if (resources.Resources == null)
            throw new InvalidOperationException("source gave no resource");
            if (!resources.Resources.Any(res => res.Type == "PackagePublish/2.0.0"))
                throw new InvalidOperationException("Source won't serve the expected push command");
            var pubRes = resources.Resources.First(res => res.Type == "PackagePublish/2.0.0");
            FileInfo fi = new FileInfo(pkg);
            if (!fi.Exists)
            {
                var report = new PushReport
                {
                    PkgName = fi.Name,
                    Message = "Le fichier n'existe pas"
                };
                return report;
            }

            try
            {
                Console.WriteLine("Connecting to "+ pubRes.Id);
                return  UploadFilesToServerUsingHttpClient.UploadFilesToServer(new Uri(pubRes.Id), fi, apikey);
            }
            catch (WebException ex)
            {
                 Console.Error.WriteLine(ex.Message);
                var report = new PushReport
                {
                    PkgName = fi.Name
                };
                report.StatusCode = ex.Status.ToString();
                report.OK = false;
                if (ex.Response != null)
                {
                    try
                    {
                        using (Stream respStream = ex.Response.GetResponseStream())
                        {
                            StreamReader sr = new StreamReader(respStream);
                            string json = sr.ReadToEnd();
                            var res = JsonConvert.DeserializeObject<IsndErrorMessage>(json);
                            report.Message = res.msg;

                            // ecode == 1 => package already present server side.
                            report.AlreadyPresent = res.ecode == 1;
                        }
                    }
                    catch (Exception iex)
                    {
                        report.Message = iex.Message;
                    }

                }

                else
                {
                    report.Message = ex.Message;
                }
                return report;
            }
            catch (Exception ex)
            {
                var report = new PushReport
                {
                    PkgName = fi.Name,
                    Message = ex.Message,
                    StackTrace = ex.StackTrace
                };
                Console.Error.WriteLine(ex.Message);
                throw;
            }
        }
    }
}