﻿/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using DotCMIS.Enums;
using DotCMIS.Exceptions;
using DotCMIS.Util;
using System.Reflection;

namespace DotCMIS.Binding.Impl
{
    internal static class HttpUtils
    {
        public delegate void Output(Stream stream);

        public static Response InvokeGET(UrlBuilder url, BindingSession session)
        {
            return Invoke(url, "GET", null, null, session, null, null, null);
        }

        public static Response InvokeGET(UrlBuilder url, BindingSession session, long? offset, long? length)
        {
            return Invoke(url, "GET", null, null, session, offset, length, null);
        }

        public static Response InvokePOST(UrlBuilder url, String contentType, Output writer, BindingSession session)
        {
            return Invoke(url, "POST", contentType, writer, session, null, null, null);
        }

        public static Response InvokePUT(UrlBuilder url, String contentType, IDictionary<string, string> headers, Output writer, BindingSession session)
        {
            return Invoke(url, "PUT", contentType, writer, session, null, null, headers);
        }

        public static Response InvokeDELETE(UrlBuilder url, BindingSession session)
        {
            return Invoke(url, "DELETE", null, null, session, null, null, null);
        }

        private static Response Invoke(UrlBuilder url, String method, String contentType, Output writer, BindingSession session,
                long? offset, long? length, IDictionary<string, string> headers)
        {
            try
            {
                // log before connect
                if (DotCMISDebug.DotCMISSwitch.TraceInfo)
                {
                    Trace.WriteLine(method + " " + url);
                }

                // create connection           
                HttpWebRequest conn = (HttpWebRequest)WebRequest.Create(url.Url);
                conn.Method = method;
                conn.UserAgent = "Apache Chemistry DotCMIS";

                // timeouts
                int connectTimeout = session.GetValue(SessionParameter.ConnectTimeout, -2);
                if (connectTimeout >= -1)
                {
                    conn.Timeout = connectTimeout;
                }

                int readTimeout = session.GetValue(SessionParameter.ReadTimeout, -2);
                if (readTimeout >= -1)
                {
                    conn.ReadWriteTimeout = readTimeout;
                }

                // set content type
                if (contentType != null)
                {
                    conn.ContentType = contentType;
                }

                // set additional headers
                if (headers != null)
                {
                    foreach (KeyValuePair<string, string> header in headers)
                    {
                        conn.Headers.Add(header.Key, header.Value);
                    }
                }

                // authenticate
                IAuthenticationProvider authProvider = session.GetAuthenticationProvider();
                if (authProvider != null)
                {
                    conn.PreAuthenticate = true;
                    authProvider.Authenticate(conn);
                }

                // range
                if (offset != null && length != null)
                {
                    if (offset < Int32.MaxValue && offset + length - 1 < Int32.MaxValue)
                    {
                        conn.AddRange((int)offset, (int)offset + (int)length - 1);
                    }
                    else
                    {
                        try
                        {
                            MethodInfo mi = conn.GetType().GetMethod("AddRange", new Type[] { typeof(Int64), typeof(Int64) });
                            mi.Invoke(conn, new object[] { offset, offset + length - 1 });
                        }
                        catch (Exception e)
                        {
                            throw new CmisInvalidArgumentException("Offset or length too big!", e);
                        }
                    }
                }
                else if (offset != null)
                {
                    if (offset < Int32.MaxValue)
                    {
                        conn.AddRange((int)offset);
                    }
                    else
                    {
                        try
                        {
                            MethodInfo mi = conn.GetType().GetMethod("AddRange", new Type[] { typeof(Int64) });
                            mi.Invoke(conn, new object[] { offset });
                        }
                        catch (Exception e)
                        {
                            throw new CmisInvalidArgumentException("Offset too big!", e);
                        }
                    }
                }

                // compression
                string compressionFlag = session.GetValue(SessionParameter.Compression) as string;
                if (compressionFlag != null && compressionFlag.ToLower().Equals("true"))
                {
                    conn.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
                }

                // send data
                if (writer != null)
                {
                    conn.SendChunked = true;
                    Stream requestStream = conn.GetRequestStream();
                    writer(requestStream);
                    requestStream.Close();
                }
                else
                {
#if __MonoCS__
                    //around for MONO HTTP DELETE issue
                    //http://stackoverflow.com/questions/11785597/monotouch-iphone-call-to-httpwebrequest-getrequeststream-connects-to-server
                    if (method == "DELETE")
                    {
                        conn.ContentLength = 0;
                        Stream requestStream = conn.GetRequestStream();
                        requestStream.Close();
                    }
#endif
                }

                // connect
                try
                {
                    HttpWebResponse response = (HttpWebResponse)conn.GetResponse();

                    if (authProvider != null)
                    {
                        authProvider.HandleResponse(response);
                    }

                    return new Response(response);
                }
                catch (WebException we)
                {
                    return new Response(we);
                }
            }
            catch (Exception e)
            {
                throw new CmisConnectionException("Cannot access " + url + ": " + e.Message, e);
            }
        }

        internal class Response
        {
            private readonly WebResponse response;

            public HttpStatusCode StatusCode { get; private set; }
            public string Message { get; private set; }
            public Stream Stream { get; private set; }
            public string ErrorContent { get; private set; }
            public string ContentType { get; private set; }
            public long? ContentLength { get; private set; }

            public Response(HttpWebResponse httpResponse)
            {
                this.response = httpResponse;
                StatusCode = httpResponse.StatusCode;
                Message = httpResponse.StatusDescription;
                ContentType = httpResponse.ContentType;
                ContentLength = httpResponse.ContentLength == -1 ? null : (long?)httpResponse.ContentLength;
                string contentTransferEncoding = httpResponse.Headers["Content-Transfer-Encoding"];
                bool isBase64 = contentTransferEncoding != null && contentTransferEncoding.Equals("base64", StringComparison.CurrentCultureIgnoreCase);

                if (httpResponse.StatusCode == HttpStatusCode.OK ||
                    httpResponse.StatusCode == HttpStatusCode.Created ||
                    httpResponse.StatusCode == HttpStatusCode.NonAuthoritativeInformation ||
                    httpResponse.StatusCode == HttpStatusCode.PartialContent)
                {
                    if (isBase64)
                    {
                        Stream = new BufferedStream(new CryptoStream(httpResponse.GetResponseStream(), new FromBase64Transform(), CryptoStreamMode.Read), 64 * 1024);
                    }
                    else
                    {
                        Stream = new BufferedStream(httpResponse.GetResponseStream(), 64 * 1024);
                    }
                }
                else
                {
                    try { httpResponse.Close(); }
                    catch (Exception) { }
                }
            }

            public Response(WebException exception)
            {
                response = exception.Response;

                HttpWebResponse httpResponse = response as HttpWebResponse;
                if (httpResponse != null)
                {
                    StatusCode = httpResponse.StatusCode;
                    Message = httpResponse.StatusDescription;
                    ContentType = httpResponse.ContentType;

                    if (ContentType != null && ContentType.ToLower().StartsWith("text/"))
                    {
                        StringBuilder sb = new StringBuilder();

                        using (StreamReader sr = new StreamReader(httpResponse.GetResponseStream()))
                        {
                            string s;
                            while ((s = sr.ReadLine()) != null)
                            {
                                sb.Append(s);
                                sb.Append('\n');
                            }
                        }

                        ErrorContent = sb.ToString();
                    }
                }
                else
                {
                    StatusCode = HttpStatusCode.InternalServerError;
                    Message = exception.Status.ToString();
                }

                try { response.Close(); }
                catch (Exception) { }
            }

            public void CloseStream()
            {
                if (Stream != null)
                {
                    Stream.Close();
                }
            }
        }
    }

    internal class UrlBuilder
    {
        private UriBuilder uri;

        public Uri Url
        {
            get { return uri.Uri; }
        }

        public UrlBuilder(string url)
        {
            if (url == null)
            {
                throw new ArgumentNullException("url");
            }

            uri = new UriBuilder(url);
        }

        public UrlBuilder AddParameter(string name, object value)
        {
            if ((name == null) || (value == null))
            {
                return this;
            }

            string valueStr = Uri.EscapeDataString(UrlBuilder.NormalizeParameter(value));

            if (uri.Query != null && uri.Query.Length > 1)
            {
                uri.Query = uri.Query.Substring(1) + "&" + name + "=" + valueStr;
            }
            else
            {
                uri.Query = name + "=" + valueStr;
            }

            return this;
        }

        public static string NormalizeParameter(object value)
        {
            if (value == null)
            {
                return null;
            }
            else if (value is Enum)
            {
                return ((Enum)value).GetCmisValue();
            }
            else if (value is bool)
            {
                return (bool)value ? "true" : "false";
            }

            return value.ToString();
        }

        public override string ToString()
        {
            return Url.ToString();
        }
    }

    internal class MimeHelper
    {
        public const string ContentDisposition = "Content-Disposition";
        public const string DispositionAttachment = "attachment";
        public const string DispositionFilename = "filename";

        private const string MIMESpecials = "()<>@,;:\\\"/[]?=" + "\t ";
        private const string RFC2231Specials = "*'%" + MIMESpecials;
        private static char[] HexDigits = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };

        public static string EncodeContentDisposition(string disposition, string filename)
        {
            if (disposition == null)
            {
                disposition = DispositionAttachment;
            }
            return disposition + EncodeRFC2231(DispositionFilename, filename);
        }

        protected static string EncodeRFC2231(string key, string value)
        {
            StringBuilder buf = new StringBuilder();
            bool encoded = EncodeRFC2231value(value, buf);
            if (encoded)
            {
                return "; " + key + "*=" + buf.ToString();
            }
            else
            {
                return "; " + key + "=" + value;
            }
        }

        protected static bool EncodeRFC2231value(string value, StringBuilder buf)
        {
            buf.Append("UTF-8");
            buf.Append("''"); // no language
            byte[] bytes;
            try
            {
                bytes = UTF8Encoding.UTF8.GetBytes(value);
            }
            catch (Exception)
            {
                return true;
            }

            bool encoded = false;
            for (int i = 0; i < bytes.Length; i++)
            {
                int ch = bytes[i] & 0xff;
                if (ch <= 32 || ch >= 127 || RFC2231Specials.IndexOf((char)ch) != -1)
                {
                    buf.Append('%');
                    buf.Append(HexDigits[ch >> 4]);
                    buf.Append(HexDigits[ch & 0xf]);
                    encoded = true;
                }
                else
                {
                    buf.Append((char)ch);
                }
            }
            return encoded;
        }
    }
}
