/*
 *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef WEBRTC_BASE_HTTPCOMMON_INL_H__
#define WEBRTC_BASE_HTTPCOMMON_INL_H__

#include "webrtc/base/common.h"
#include "webrtc/base/httpcommon.h"

namespace rtc {

///////////////////////////////////////////////////////////////////////////////
// Url
///////////////////////////////////////////////////////////////////////////////

template<class CTYPE>
void Url<CTYPE>::do_set_url(const CTYPE* val, size_t len) {
  if (ascnicmp(val, "http://", 7) == 0) {
    val += 7; len -= 7;
    secure_ = false;
  } else if (ascnicmp(val, "https://", 8) == 0) {
    val += 8; len -= 8;
    secure_ = true;
  } else {
    clear();
    return;
  }
  const CTYPE* path = strchrn(val, len, static_cast<CTYPE>('/'));
  if (!path) {
    path = val + len;
  }
  size_t address_length = (path - val);
  do_set_address(val, address_length);
  do_set_full_path(path, len - address_length);
}

template<class CTYPE>
void Url<CTYPE>::do_set_address(const CTYPE* val, size_t len) {
  if (const CTYPE* at = strchrn(val, len, static_cast<CTYPE>('@'))) {
    // Everything before the @ is a user:password combo, so skip it.
    len -= at - val + 1;
    val = at + 1;
  }
  if (const CTYPE* colon = strchrn(val, len, static_cast<CTYPE>(':'))) {
    host_.assign(val, colon - val);
    // Note: In every case, we're guaranteed that colon is followed by a null,
    // or non-numeric character.
    port_ = static_cast<uint16>(::strtoul(colon + 1, NULL, 10));
    // TODO: Consider checking for invalid data following port number.
  } else {
    host_.assign(val, len);
    port_ = HttpDefaultPort(secure_);
  }
}

template<class CTYPE>
void Url<CTYPE>::do_set_full_path(const CTYPE* val, size_t len) {
  const CTYPE* query = strchrn(val, len, static_cast<CTYPE>('?'));
  if (!query) {
    query = val + len;
  }
  size_t path_length = (query - val);
  if (0 == path_length) {
    // TODO: consider failing in this case.
    path_.assign(1, static_cast<CTYPE>('/'));
  } else {
    ASSERT(val[0] == static_cast<CTYPE>('/'));
    path_.assign(val, path_length);
  }
  query_.assign(query, len - path_length);
}

template<class CTYPE>
void Url<CTYPE>::do_get_url(string* val) const {
  CTYPE protocol[9];
  asccpyn(protocol, ARRAY_SIZE(protocol), secure_ ? "https://" : "http://");
  val->append(protocol);
  do_get_address(val);
  do_get_full_path(val);
}

template<class CTYPE>
void Url<CTYPE>::do_get_address(string* val) const {
  val->append(host_);
  if (port_ != HttpDefaultPort(secure_)) {
    CTYPE format[5], port[32];
    asccpyn(format, ARRAY_SIZE(format), ":%hu");
    sprintfn(port, ARRAY_SIZE(port), format, port_);
    val->append(port);
  }
}

template<class CTYPE>
void Url<CTYPE>::do_get_full_path(string* val) const {
  val->append(path_);
  val->append(query_);
}

template<class CTYPE>
bool Url<CTYPE>::get_attribute(const string& name, string* value) const {
  if (query_.empty())
    return false;

  std::string::size_type pos = query_.find(name, 1);
  if (std::string::npos == pos)
    return false;

  pos += name.length() + 1;
  if ((pos > query_.length()) || (static_cast<CTYPE>('=') != query_[pos-1]))
    return false;

  std::string::size_type end = query_.find(static_cast<CTYPE>('&'), pos);
  if (std::string::npos == end) {
    end = query_.length();
  }
  value->assign(query_.substr(pos, end - pos));
  return true;
}

///////////////////////////////////////////////////////////////////////////////

}  // namespace rtc

#endif  // WEBRTC_BASE_HTTPCOMMON_INL_H__
