/*
 *
 * 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.
 *
 */

#include "proton/url.hpp"

#include "proton/error.hpp"

#include "proton_bits.hpp"

#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <sstream>
#include <vector>

namespace {

/** URL-encode src and append to dst. */
static std::string pni_urlencode(const std::string &src) {
    static const char *bad = "@:/%[]?#";

    std::ostringstream dst;
    dst << std::hex << std::uppercase << std::setfill('0');

    std::size_t i = 0;
    std::size_t j = src.find_first_of(bad);
    while (j!=std::string::npos) {
        dst << src.substr(i, j-i);
        dst << "%" << std::setw(2) << int(src[j]);
        i = j + 1;
        j = src.find_first_of(bad, i);
    }
    dst << src.substr(i);
    return dst.str();
}

// Low level url parser
static void pni_urldecode(const char *src, char *dst)
{
  const char *in = src;
  char *out = dst;
  while (*in != '\0')
  {
    if ('%' == *in)
    {
      if ((in[1] != '\0') && (in[2] != '\0'))
      {
        char esc[3];
        esc[0] = in[1];
        esc[1] = in[2];
        esc[2] = '\0';
        unsigned long d = std::strtoul(esc, NULL, 16);
        *out = (char)d;
        in += 3;
        out++;
      }
      else
      {
        *out = *in;
        in++;
        out++;
      }
    }
    else
    {
      *out = *in;
      in++;
      out++;
    }
  }
  *out = '\0';
}

void parse_url(char *url, const char **scheme, const char **user, const char **pass, const char **host, const char **port, const char **path)
{
  if (!url) return;

  char *slash = std::strchr(url, '/');

  if (slash && slash>url) {
    char *scheme_end = std::strstr(slash-1, "://");

    if (scheme_end && scheme_end<slash) {
      *scheme_end = '\0';
      *scheme = url;
      url = scheme_end + 3;
      slash = std::strchr(url, '/');
    }
  } else if (0 == strncmp(url, "//", 2)) {
      url += 2;
      slash = std::strchr(url, '/');
  }

  if (slash) {
    *slash = '\0';
    *path = slash + 1;
  }

  char *at = std::strchr(url, '@');
  if (at) {
    *at = '\0';
    char *up = url;
    url = at + 1;
    char *colon = std::strchr(up, ':');
    if (colon) {
      *colon = '\0';
      char *p = colon + 1;
      pni_urldecode(p, p);
      *pass = p;
    }
    pni_urldecode(up, up);
    *user = up;
  }

  *host = url;
  char *open = (*url == '[') ? url : 0;
  if (open) {
    char *close = std::strchr(open, ']');
    if (close) {
        *host = open + 1;
        *close = '\0';
        url = close + 1;
    }
  }

  char *colon = std::strchr(url, ':');
  if (colon) {
    *colon = '\0';
    *port = colon + 1;
  }
}

} // namespace

namespace proton {

struct url::impl {
    static const char* const default_host;
    const char* scheme;
    const char* username;
    const char* password;
    const char* host;
    const char* port;
    const char* path;
    std::vector<char> cstr;
    mutable std::string str;

    impl(const std::string& s) :
        scheme(0), username(0), password(0), host(0), port(0), path(0),
        cstr(s.size()+1, '\0')
    {
        std::copy(s.begin(), s.end(), cstr.begin());
        parse_url(&cstr[0], &scheme, &username, &password, &host, &port, &path);
    }

    void defaults() {
        if (!scheme || *scheme=='\0' ) scheme = proton::url::AMQP.c_str();
        if (!host || *host=='\0' ) host = default_host;
        if (!port || *port=='\0' ) port = scheme;
    }

    operator std::string() const {
        if ( str.empty() ) {
            if (scheme) {
                str += scheme;
                str += "://";
            }
            if (username) {
                str += pni_urlencode(username);
            }
            if (password) {
                str += ":";
                str += pni_urlencode(password);
            }
            if (username || password) {
                str += "@";
            }
            if (host) {
                if (std::strchr(host, ':')) {
                    str += '[';
                    str += host;
                    str += ']';
                } else {
                    str += host;
                }
            }
            if (port) {
                str += ':';
                str += port;
            }
            if (path) {
                str += '/';
                str += path;
            }
        }
        return str;
    }

};

const char* const url::impl::default_host = "localhost";


url_error::url_error(const std::string& s) : error(s) {}
url_error::~url_error() throw() {}

url::url(const std::string &s) : impl_(new impl(s)) { impl_->defaults(); }

url::url(const std::string &s, bool d) : impl_(new impl(s)) { if (d) impl_->defaults(); }

url::url(const url& u) : impl_(new impl(u)) {}

url::~url() {}

url& url::operator=(const url& u) {
    if (this != &u) {
        impl_.reset(new impl(*u.impl_));
    }
    return *this;
}

url::operator std::string() const { return *impl_; }

std::string url::scheme() const { return str(impl_->scheme); }
std::string url::user() const { return str(impl_->username); }
std::string url::password() const { return str(impl_->password); }
std::string url::host() const { return str(impl_->host); }
std::string url::port() const { return str(impl_->port); }
std::string url::path() const { return str(impl_->path); }

std::string url::host_port() const { return host() + ":" + port(); }

bool url::empty() const { return impl_->str.empty(); }

const std::string url::AMQP("amqp");
const std::string url::AMQPS("amqps");

uint16_t url::port_int() const {
    if (port() == AMQP) return 5672;
    if (port() == AMQPS) return 5671;
    std::istringstream is(port());
    uint16_t result;
    is >> result;
    if (is.fail())
        throw url_error("invalid port '" + port() + "'");
    return result;
}

std::ostream& operator<<(std::ostream& o, const url& u) {
    return o << std::string(u);
}

std::string to_string(const url& u) {
    return u;
}

std::istream& operator>>(std::istream& i, url& u) {
    std::string s;
    i >> s;
    if (!i.fail()) {
        url::impl* p = new url::impl(s);
        p->defaults();
        u.impl_.reset(p);
    }
    return i;
}

} // namespace proton
