﻿/*
* 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 PortCMIS.Enums;
using System;
using System.Globalization;
using System.Numerics;
using System.Text;

namespace PortCMIS.Binding
{
    /// <summary>
    /// This class assembles URLs.
    /// </summary>
    public class UrlBuilder
    {
        private UriBuilder uri;

        /// <value>
        /// The current URL.
        /// </value>
        public Uri Url
        {
            get { return uri.Uri; }
        }

        /// <summary>
        /// Creates a new instance with a given URL.
        /// </summary>
        /// <param name="url">the URL</param>
        public UrlBuilder(string url)
        {
            if (url == null)
            {
                throw new ArgumentNullException(nameof(url));
            }

            uri = new UriBuilder(url);
        }

        /// <summary>
        /// Creates a new instance with a given URL.
        /// </summary>
        /// <param name="url">the URL</param>
        public UrlBuilder(Uri url)
        {
            if (url == null)
            {
                throw new ArgumentNullException(nameof(url));
            }

            uri = new UriBuilder(url);
        }

        /// <summary>
        /// Adds a parameter.
        /// </summary>
        /// <param name="name">the parameter name</param>
        /// <param name="value">the parameter value</param>
        /// <returns>this UrlBuilder object</returns>
        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;
        }

        /// <summary>
        /// Adds to the URL path.
        /// </summary>
        /// <param name="path">the path</param>
        /// <returns>this UrlBuilder object</returns>
        public UrlBuilder AddPath(string path)
        {
            return AddPathPart(path, false);
        }

        /// <summary>
        /// Adds to the URL path.
        /// </summary>
        /// <param name="part">the path part</param>
        /// <param name="quoteSlash">indicator whether slashes should be quoted or not</param>
        /// <returns>this UrlBuilder object</returns>
        protected UrlBuilder AddPathPart(string part, bool quoteSlash)
        {
            if (String.IsNullOrEmpty(part))
            {
                return this;
            }
            if (uri.Path.Length == 0 || uri.Path[uri.Path.Length - 1] != '/')
            {
                uri.Path += "/";
            }
            if (part[0] == '/')
            {
                part = part.Substring(1);
            }
            uri.Path += QuoteURIPathComponent(part, quoteSlash);

            return this;
        }


        private static readonly char[] RFC7232Reserved = ";?:@&=+$,[]".ToCharArray();

        private string QuoteURIPathComponent(string s, bool quoteSlash)
        {
            if (String.IsNullOrEmpty(s))
            {
                return s;
            }

            StringBuilder result = new StringBuilder(s);

            foreach (char c in RFC7232Reserved)
            {
                result.Replace(c.ToString(), "%" + Convert.ToByte(c, CultureInfo.InvariantCulture).ToString("X", CultureInfo.InvariantCulture));
            }

            if (quoteSlash)
            {
                result.Replace("/", "%2F");
            }

            return result.ToString();
        }

        /// <summary>
        /// Normalizes a parameter value.
        /// </summary>
        /// <param name="value">the value</param>
        /// <returns>the normalized value as string</returns>
        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";
            }
            else if (value is BigInteger)
            {
                return ((BigInteger)value).ToString("0", CultureInfo.InvariantCulture);
            }

            return value.ToString();
        }

        /// <summary>
        /// Returns the current URL.
        /// </summary>
        /// <returns>the current URL</returns>
        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 readonly char[] HexDigits = { '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 = Encoding.UTF8.GetBytes(value);
            }
            catch
            {
                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;
        }
    }
}
