/**
  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.
 */
/**
 * @file Request.cc
 */

#include "tscpp/api/Request.h"
#include "ts/ts.h"
#include "tscpp/api/noncopyable.h"
#include "utils_internal.h"
#include "logging_internal.h"

using namespace atscppapi;
using std::string;

/**
 * @private
 */
struct atscppapi::RequestState : noncopyable {
  TSMBuffer hdr_buf_ = nullptr;
  TSMLoc    hdr_loc_ = nullptr;
  TSMLoc    url_loc_ = nullptr;
  Url       url_;
  Headers   headers_;
  /* method and version are stored here for the case of an unbound request */
  HttpMethod  method_      = HTTP_METHOD_UNKNOWN;
  HttpVersion version_     = HTTP_VERSION_UNKNOWN;
  bool        destroy_buf_ = false;
  RequestState()           = default;
};

Request::Request()
{
  state_ = std::make_unique<RequestState>();
}

Request::Request(void *hdr_buf, void *hdr_loc)
{
  state_ = std::make_unique<RequestState>();
  init(hdr_buf, hdr_loc);
  LOG_DEBUG("Initialized request object %p with hdr_buf=%p and hdr_loc=%p", this, hdr_buf, hdr_loc);
}

Request::Request(const string &url_str, HttpMethod method, HttpVersion version)
{
  state_               = std::make_unique<RequestState>();
  state_->method_      = method;
  state_->version_     = version;
  state_->destroy_buf_ = true;
  state_->hdr_buf_     = TSMBufferCreate();
  if (TSUrlCreate(state_->hdr_buf_, &state_->url_loc_) == TS_SUCCESS) {
    const char *url_str_start = url_str.c_str();
    const char *url_str_end   = url_str_start + url_str.size();
    if (TSUrlParse(state_->hdr_buf_, state_->url_loc_, &url_str_start, url_str_end) != TS_PARSE_DONE) {
      LOG_ERROR("[%s] does not represent a valid url", url_str.c_str());
    } else {
      state_->url_.init(state_->hdr_buf_, state_->url_loc_);
    }
  } else {
    state_->url_loc_ = nullptr;
    LOG_ERROR("Could not create URL field; hdr_buf %p", state_->hdr_buf_);
  }
}

void
Request::init(void *hdr_buf, void *hdr_loc)
{
  reset();
  if (!hdr_buf || !hdr_loc) {
    return;
  }
  state_->hdr_buf_ = static_cast<TSMBuffer>(hdr_buf);
  state_->hdr_loc_ = static_cast<TSMLoc>(hdr_loc);
  state_->headers_.reset(state_->hdr_buf_, state_->hdr_loc_);
  state_->url_loc_ = nullptr;
  TSReturnCode ret = TSHttpHdrUrlGet(state_->hdr_buf_, state_->hdr_loc_, &state_->url_loc_);
  if (!state_->url_loc_ and ret != TS_SUCCESS) {
    LOG_ERROR("TSHttpHdrUrlGet returned a null url loc, hdr_buf=%p, hdr_loc=%p", state_->hdr_buf_, state_->hdr_loc_);
  } else {
    state_->url_.init(state_->hdr_buf_, state_->url_loc_);
    LOG_DEBUG("Initialized url");
  }
}

void
Request::reset()
{
  state_->hdr_buf_ = nullptr;
  state_->hdr_loc_ = nullptr;
  state_->headers_.reset(nullptr, nullptr);
  state_->url_loc_ = nullptr;
  LOG_DEBUG("Reset request %p", this);
}

HttpMethod
Request::getMethod() const
{
  if (state_->hdr_buf_ && state_->hdr_loc_) {
    int         method_len;
    const char *method_str = TSHttpHdrMethodGet(state_->hdr_buf_, state_->hdr_loc_, &method_len);
    if (method_str && method_len) {
      if (method_str == TS_HTTP_METHOD_GET) {
        state_->method_ = HTTP_METHOD_GET;
      } else if (method_str == TS_HTTP_METHOD_POST) {
        state_->method_ = HTTP_METHOD_POST;
      } else if (method_str == TS_HTTP_METHOD_HEAD) {
        state_->method_ = HTTP_METHOD_HEAD;
      } else if (method_str == TS_HTTP_METHOD_CONNECT) {
        state_->method_ = HTTP_METHOD_CONNECT;
      } else if (method_str == TS_HTTP_METHOD_DELETE) {
        state_->method_ = HTTP_METHOD_DELETE;
      } else if (method_str == TS_HTTP_METHOD_OPTIONS) {
        state_->method_ = HTTP_METHOD_OPTIONS;
      } else if (method_str == TS_HTTP_METHOD_PURGE) {
        state_->method_ = HTTP_METHOD_PURGE;
      } else if (method_str == TS_HTTP_METHOD_QUERY) {
        state_->method_ = HTTP_METHOD_QUERY;
      } else if (method_str == TS_HTTP_METHOD_PUT) {
        state_->method_ = HTTP_METHOD_PUT;
      } else if (method_str == TS_HTTP_METHOD_TRACE) {
        state_->method_ = HTTP_METHOD_TRACE;
      } else if (method_str == TS_HTTP_METHOD_PUSH) {
        state_->method_ = HTTP_METHOD_PUSH;
      }
      LOG_DEBUG("Request method=%d [%s] on hdr_buf=%p, hdr_loc=%p", state_->method_, HTTP_METHOD_STRINGS[state_->method_].c_str(),
                state_->hdr_buf_, state_->hdr_loc_);
    } else {
      LOG_ERROR(
        "TSHttpHdrMethodGet returned null string or it was zero length, hdr_buf=%p, hdr_loc=%p, method str=%p, method_len=%d",
        state_->hdr_buf_, state_->hdr_loc_, method_str, method_len);
    }
  }
  return state_->method_;
}

Url &
Request::getUrl()
{
  return state_->url_;
}

atscppapi::HttpVersion
Request::getVersion() const
{
  if (state_->hdr_buf_ && state_->hdr_loc_) {
    state_->version_ = utils::internal::getHttpVersion(state_->hdr_buf_, state_->hdr_loc_);
    LOG_DEBUG("Request version=%d [%s] on hdr_buf=%p, hdr_loc=%p", state_->version_, HTTP_VERSION_STRINGS[state_->version_].c_str(),
              state_->hdr_buf_, state_->hdr_loc_);
  }
  return state_->version_;
}

atscppapi::Headers &
Request::getHeaders() const
{
  return state_->headers_;
}

void
Request::setHost(std::string const &host)
{
  static const std::string HOST_FIELD_NAME(TS_MIME_FIELD_HOST, TS_MIME_LEN_HOST);

  if (state_->hdr_buf_ && state_->hdr_loc_) {
    Url &url = this->getUrl();

    // Update the URL if it has a host currently.
    if (!url.getHost().empty()) {
      url.setHost(host);
    }

    // Force a HOST field.
    this->getHeaders().set(HOST_FIELD_NAME, host);
  }
}

Request::~Request()
{
  if (state_->url_loc_) {
    if (state_->destroy_buf_) {
      // usually, hdr_loc is the parent of url_loc, but we created this url_loc "directly" in hdr_buf,
      // so we use null as parent loc in this case
      TSMLoc null_parent_loc = nullptr;
      TSHandleMLocRelease(state_->hdr_buf_, null_parent_loc, state_->url_loc_);
      TSMBufferDestroy(state_->hdr_buf_);
    }
  }
}
