/*
 *
 * 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() {}

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() && !i.bad()) {
        if (!s.empty()) {
            url::impl* p = new url::impl(s);
            p->defaults();
            u.impl_.reset(p);
        } else {
            i.clear(std::ios::failbit);
        }
    }
    return i;
}

} // namespace proton
