using System;
using System.IO;
using System.Net;
using System.Text;
using System.Linq;

namespace ZionVault.WebService
{
    public class Client
    {
        private string server;

        public Client(string server)
        {
            this.server = server;
        }

        private string ReadResponse(WebResponse response)
        {
            Stream dataStream = response.GetResponseStream();
            StreamReader reader = new StreamReader(dataStream, Encoding.UTF8);
            string result = reader.ReadToEnd();
            reader.Close();
            dataStream.Close();
            response.Close();
            return result;
        }

        public string _request(string method, string uri, string user, string pass = null, string data = null, string file = null)
        {
            try
            {
                string[] newdata = { data };

                return this._request(method, uri, user, pass, newdata, file);

            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        public string _request(string method, string uri, string user, string pass = null, string[] data = null, string file = null)
        {
            try
            {
                switch (method)
                {
                    case "GET":
                        return this._get(uri, user, pass);
                    case "PUT":
                        return this._put(uri, user, pass, data);
                    case "POST":
                        return this._post(uri, user, pass, data, file);
                    default:
                        return null;
                }

            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private string _get(string uri, string user, string pass)
        {
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(
                string.Format("{0}{1}", this.server, uri)
                ); 
            request.Timeout = -1;
            request.KeepAlive = true;
            request.Method = "GET";
            request.ContentType = "application/json";
            // request.Headers.Add("Authorization", string.Format("Basic {0}", System.Convert.ToBase64String(
            //            System.Text.Encoding.GetEncoding("UTF-8").GetBytes(user + ":" + pass))));
            request.Headers.Add("Authorization", string.Format("Bearer {0}", user));
            try
            {
                string resp = string.Empty;
                //string resp = this.ReadResponse(request.GetResponse());
                using(HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                using(Stream dataStream = response.GetResponseStream())
                using(StreamReader reader = new StreamReader(dataStream, Encoding.UTF8))
                {
                    resp = reader.ReadToEnd();
                }
                return resp;
            }
            catch (WebException ex)
            {
                throw ex;
            }
        }

        private string _put(string uri, string user, string pass, string[] data)
        {
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(string.Format("{0}{1}", this.server, uri));
            request.Timeout = -1;
            request.KeepAlive = true;
            request.Method = "PUT";
            request.ContentType = "application/json";
            // request.Headers.Add("Authorization", string.Format("Basic {0}", System.Convert.ToBase64String(
            //            System.Text.Encoding.GetEncoding("UTF-8").GetBytes(user + ":" + pass))));
            request.Headers.Add("Authorization", string.Format("Bearer {0}", user));

            if (data != null)
            {
                byte[] byteArray = Encoding.UTF8.GetBytes(data[0]);
                request.ContentLength = byteArray.Length;
                request.GetRequestStream().Write(byteArray, 0, byteArray.Length);
            }
            try
            {
                string resp = this.ReadResponse(request.GetResponse());
                return resp;

                System.Threading.Thread.Sleep(500);
            }
            catch (WebException ex)
            {
                //System.IO.File.AppendAllText(@"C:\Robot\Logs\API_PUT_ERROR.txt", string.Format("{0} - {1}\n", uri, string.Join("", data)));
                 throw new Exception("Erro");
            }
        }
        private string _post(string uri, string user, string pass, string[] data, string file = "")
        {
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(string.Format("{0}{1}", this.server, uri));
            request.Method = "POST";
            request.ContentType = "application/json";
            // request.Headers.Add("Authorization", string.Format("Basic {0}", System.Convert.ToBase64String(
            //            System.Text.Encoding.GetEncoding("UTF-8").GetBytes(user + ":" + pass))));
            request.Headers.Add("Authorization", string.Format("Bearer {0}", user));

            if (data != null)
            {
                byte[] byteArray = Encoding.UTF8.GetBytes(data[0]);
                request.ContentLength = byteArray.Length;
                request.GetRequestStream().Write(byteArray, 0, byteArray.Length);
            }
            try
            {
                string resp = this.ReadResponse(request.GetResponse());
                return resp;
            }
            catch (WebException ex)
            {
                throw ex;
            }
        }
/*
        private string _post(string uri, string user, string pass, string[] data = null, string file = "")
        {
            string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
            byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");


            string url = string.Format("{0}{1}", this.server, uri);

            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
            request.Method = "POST";
            request.ContentType = "multipart/form-data; boundary=" + boundary;
            request.KeepAlive = true;

            request.Headers.Add("Authorization", string.Format("Basic {0}", System.Convert.ToBase64String(
                        System.Text.Encoding.GetEncoding("UTF-8").GetBytes(user + ":" + pass))));

            Stream stream = request.GetRequestStream();

            stream.Write(boundarybytes, 0, boundarybytes.Length);

            if (data != null)
            {
                foreach (string info in data)
                {
                    byte[] formitembytes = Encoding.UTF8.GetBytes(info);
                    stream.Write(formitembytes, 0, formitembytes.Length);
                    stream.Write(boundarybytes, 0, boundarybytes.Length);
                }
            }

            if (file != null && file != string.Empty)
            {
                string type = Util.MimeType.Get(file);

                string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n";
                byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(
                string.Format(headerTemplate, "file", file, type));
                stream.Write(headerbytes, 0, headerbytes.Length);

                FileStream fileStream = new FileStream(file, FileMode.Open, FileAccess.Read);
                byte[] buffer = new byte[4096];
                int bytesRead = 0;
                while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
                {
                    stream.Write(buffer, 0, bytesRead);
                }
                fileStream.Close();

                byte[] trailer = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");
                stream.Write(trailer, 0, trailer.Length);
            }

            stream.Close();

            try
            {
                return this.ReadResponse(request.GetResponse());
            }
            catch (WebException ex)
            {
                throw ex;
            }
        }
            */
        public static string FormItem(string name, string value)
        {
            return string.Format("Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}", name, value);
        }
    }
}
