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

#pragma once

/**
 An ATS Http header exists in a marshall buffer at a given location.
 Unfortunately how that marshall buffer is created and how that
 location is determined depends on where those buffers came from.

 A TSHttpTxn manages the buffer itself and creates a location which
 has to be managed.

 A TSHttpParsed populates a created buffer that has had TSHttpHdrCreate
 run against it which creates a location against it.  End users
 need to manage the created buffer, the location and invoke
 TSHttpHdrDestroy.
*/

#include "ts/ts.h"

#include <string>

constexpr std::string_view SLICE_CRR_HEADER = {"Slice-Crr-Status"};
constexpr std::string_view SLICE_CRR_VAL    = "1";

// extent of the object a PURGE removed, reported by ATS on a successful purge.
// Emitted by HttpTransact::delete_all_document_alternates_and_return.
constexpr std::string_view PURGED_CONTENT_RANGE = {"X-Purged-Content-Range"};

/**
  Designed to be a cheap throwaway struct which allows a
  consumer to make various calls to manipulate headers.
*/
struct HttpHeader {
  TSMBuffer const m_buffer;
  TSMLoc const    m_lochdr;

  explicit HttpHeader(TSMBuffer buffer, TSMLoc lochdr) : m_buffer(buffer), m_lochdr(lochdr) {}

  bool
  isValid() const
  {
    return nullptr != m_buffer && nullptr != m_lochdr;
  }

  int
  byteSize() const
  {
    if (isValid()) {
      return TSHttpHdrLengthGet(m_buffer, m_lochdr);
    } else {
      return 0;
    }
  }

  // TS_HTTP_TYPE_UNKNOWN, TS_HTTP_TYPE_REQUEST, TS_HTTP_TYPE_RESPONSE
  TSHttpType type() const;

  TSHttpStatus status() const;

  bool setStatus(TSHttpStatus const newstatus);

  bool setUrl(TSMBuffer const bufurl, TSMLoc const locurl);

  using CharPtrGetFunc = const char *(*)(TSMBuffer, TSMLoc, int *);

  // request method TS_HTTP_METHOD_*
  char const *
  method(int *const len = nullptr) const
  {
    return getCharPtr(TSHttpHdrMethodGet, len);
  }

  // request method version
  int
  version() const
  {
    return TSHttpHdrVersionGet(m_buffer, m_lochdr);
  }

  // Returns string representation of the url. Caller gets ownership!
  char *urlString(int *const urllen) const;

  // host
  char const *
  hostname(int *const len) const
  {
    return getCharPtr(TSHttpHdrHostGet, len);
  }

  // response reason
  char const *
  reason(int *const len) const
  {
    return getCharPtr(TSHttpHdrReasonGet, len);
  }

  bool setReason(char const *const valstr, int const vallen);

  bool hasKey(char const *const key, int const keylen) const;

  // removes all fields (including duplicates) matching this key.
  // returns false if header invalid or any removal fails.
  bool removeKey(char const *const key, int const keylen);

  // retrieves header value as a null terminated char* in valstr.
  // caller must ensure the valstr buffer has sufficient capacity.
  // null termination only guaranteed on success.
  bool valueForKey(char const *const keystr, int const keylen,
                   char *const valstr,    // <-- return string value
                   int *const  vallen,    // <-- pass in capacity, returns len of string
                   int const   index = -1 // retrieves all values
  ) const;

  /**
    Sets or adds a key/value
  */
  bool setKeyVal(char const *const key, int const keylen, char const *const val, int const vallen,
                 int const index = -1 // sets all values
  );

  // retrieves header value as a time_t
  bool timeForKey(char const *const keystr, int const keylen, time_t *const timeval) const;

  // sets header value as a time_t
  bool setKeyTime(char const *const key, int const keylen, time_t const timeval);

  /** dump header into provided char buffer
   */
  std::string toString() const;

private:
  /**
    To be used with
    TSHttpHdrMethodGet
    TSHttpHdrHostGet
    TSHttpHdrReasonGet
   */
  char const *getCharPtr(CharPtrGetFunc func, int *const len) const;
};

struct TxnHdrMgr {
  TxnHdrMgr(TxnHdrMgr const &)            = delete;
  TxnHdrMgr &operator=(TxnHdrMgr const &) = delete;

  TSMBuffer m_buffer{nullptr};
  TSMLoc    m_lochdr{nullptr};

  TxnHdrMgr() : m_buffer(nullptr), m_lochdr(nullptr) {}
  ~TxnHdrMgr()
  {
    if (nullptr != m_lochdr) {
      TSHandleMLocRelease(m_buffer, TS_NULL_MLOC, m_lochdr);
    }
  }

  using HeaderGetFunc = TSReturnCode (*)(TSHttpTxn, TSMBuffer *, TSMLoc *);
  /** use one of the following:
    TSHttpTxnClientReqGet
    TSHttpTxnClientRespGet
    TSHttpTxnServerReqGet
    TSHttpTxnServerRespGet
    TSHttpTxnCachedReqGet
    TSHttpTxnCachedRespGet
  */

  bool
  populateFrom(TSHttpTxn const &txnp, HeaderGetFunc const &func)
  {
    return TS_SUCCESS == func(txnp, &m_buffer, &m_lochdr);
  }

  bool
  isValid() const
  {
    return nullptr != m_lochdr;
  }
};

struct HdrMgr {
  HdrMgr(HdrMgr const &)            = delete;
  HdrMgr &operator=(HdrMgr const &) = delete;

  TSMBuffer m_buffer{nullptr};
  TSMLoc    m_lochdr{nullptr};

  HdrMgr() : m_buffer(nullptr), m_lochdr(nullptr) {}
  ~HdrMgr()
  {
    if (nullptr != m_buffer) {
      if (nullptr != m_lochdr) {
        TSHttpHdrDestroy(m_buffer, m_lochdr);
        TSHandleMLocRelease(m_buffer, TS_NULL_MLOC, m_lochdr);
      }
      TSMBufferDestroy(m_buffer);
    }
  }

  /** Create an owned HTTP/1.1 response header with the given status.
   *
   * For a response slice forms itself, with no server response to relay. An
   * intercept is an HTTP/1.x channel, so the version is not negotiable.
   */
  bool create_response(TSHttpStatus const status);

  void
  resetHeader()
  {
    if (nullptr != m_buffer && nullptr != m_lochdr) {
      TSHttpHdrDestroy(m_buffer, m_lochdr);
      TSHandleMLocRelease(m_buffer, TS_NULL_MLOC, m_lochdr);
      m_lochdr = nullptr;
    }
  }

  using HeaderParseFunc = TSParseResult (*)(TSHttpParser, TSMBuffer, TSMLoc, const char **, const char *);

  /** Clear/create the parser before calling this and don't
   use the parser on another header until done with this one.
   use one of the following:
     TSHttpHdrParseReq
     TSHttpHdrParseResp
    Call this multiple times if necessary.
  */
  TSParseResult populateFrom(TSHttpParser const http_parser, TSIOBufferReader const reader, HeaderParseFunc const parsefunc,
                             int64_t *const consumed);

  bool
  isValid() const
  {
    return nullptr != m_lochdr;
  }
};
