/** @file

  A brief file description

  @section license License

  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 "proxy/http/remap/RemapProcessor.h"

using namespace std::literals;

RemapProcessor remapProcessor;

namespace
{
DbgCtl dbg_ctl_url_rewrite{"url_rewrite"};

} // end anonymous namespace
/**
  Most of this comes from UrlRewrite::Remap(). Generally, all this does
  is set "map" to the appropriate entry from the HttpSM's leased m_remap
  such that we will then have access to the correct url_mapping inside
  perform_remap.

*/
bool
RemapProcessor::setup_for_remap(HttpTransact::State *s, UrlRewrite *table)
{
  Dbg(dbg_ctl_url_rewrite, "setting up for remap: %p", s);
  URL     *request_url    = nullptr;
  bool     mapping_found  = false;
  HTTPHdr *request_header = &s->hdr_info.client_request;
  char   **redirect_url   = &s->remap_redirect;
  int      request_port;
  bool     proxy_request = false;

  s->reverse_proxy = table->reverse_proxy;
  s->url_map.set(s->hdr_info.client_request.m_heap);

  ink_assert(redirect_url != nullptr);

  if (unlikely((table->num_rules_forward == 0) && (table->num_rules_forward_with_recv_port == 0))) {
    ink_assert(table->forward_mappings.empty() && table->forward_mappings_with_recv_port.empty());
    Dbg(dbg_ctl_url_rewrite, "[lookup] No forward mappings found; Skipping...");
    return false;
  }

  // Since we are called before request validity checking
  // occurs, make sure that we have both a valid request
  // header and a valid URL
  if (unlikely(!request_header || (request_url = request_header->url_get()) == nullptr || !request_url->valid())) {
    Error("NULL or invalid request data");
    return false;
  }

  auto request_host{request_header->host_get()};
  request_port  = request_header->port_get();
  proxy_request = request_header->is_target_in_url() || !s->reverse_proxy;
  // Default to empty host.
  if (request_host.empty()) {
    request_host = ""sv;
  }

  Dbg(dbg_ctl_url_rewrite, "[lookup] attempting %s lookup", proxy_request ? "proxy" : "normal");

  if (table->num_rules_forward_with_recv_port) {
    Dbg(dbg_ctl_url_rewrite, "[lookup] forward mappings with recv port found; Using recv port %d",
        s->client_info.dst_addr.host_order_port());

    bool ret;
    if (s->client_info.dst_addr.host_order_port() == 0) {
      // Port number 0 means that UDS is used.
      // Adjust the scheme so that we can find rules with +unix suffix.
      URL adjusted_url;
      adjusted_url.create(nullptr);
      adjusted_url.copy(request_url);
      if (auto scheme = adjusted_url.scheme_get_wksidx(); scheme == URL_WKSIDX_HTTP) {
        adjusted_url.scheme_set("http+unix");
      } else if (scheme == URL_WKSIDX_HTTPS) {
        adjusted_url.scheme_set("https+unix");
      }
      Dbg(dbg_ctl_url_rewrite, "[lookup] scheme was adjusted to %.*s", static_cast<int>(adjusted_url.scheme_get().size()),
          adjusted_url.scheme_get().data());
      ret = table->forwardMappingWithRecvPortLookup(&adjusted_url, s->client_info.dst_addr.host_order_port(), request_host.data(),
                                                    static_cast<int>(request_host.length()), s->url_map);
      adjusted_url.destroy();
    } else {
      ret = table->forwardMappingWithRecvPortLookup(request_url, s->client_info.dst_addr.host_order_port(), request_host.data(),
                                                    static_cast<int>(request_host.length()), s->url_map);
    }
    if (ret) {
      Dbg(dbg_ctl_url_rewrite, "Found forward mapping with recv port");
      mapping_found = true;
    } else if (table->num_rules_forward == 0) {
      ink_assert(table->forward_mappings.empty());
      Dbg(dbg_ctl_url_rewrite, "No forward mappings left");
      return false;
    }
  }

  if (!mapping_found) {
    mapping_found = table->forwardMappingLookup(request_url, request_port, request_host.data(),
                                                static_cast<int>(request_host.length()), s->url_map);
  }

  // If no rules match and we have a host, check empty host rules since
  // they function as default rules for server requests.
  // If there's no host, we've already done this.
  if (!mapping_found && table->nohost_rules && !request_host.empty()) {
    Dbg(dbg_ctl_url_rewrite, "[lookup] nothing matched");
    mapping_found = table->forwardMappingLookup(request_url, 0, "", 0, s->url_map);
  }

  if (!proxy_request) { // do extra checks on a server request

    // Save this information for later
    // @amc: why is this done only for requests without a host in the URL?
    s->hh_info.host_len     = static_cast<int>(request_host.length());
    s->hh_info.request_host = request_host.data();
    s->hh_info.request_port = request_port;

    if (mapping_found) {
      // Downstream mapping logic (e.g., self::finish_remap())
      // apparently assumes the presence of the target in the URL, so
      // we need to copy it. Perhaps it's because it's simpler to just
      // do the remap on the URL and then fix the field at the end.
      request_header->set_url_target_from_host_field();
    }
  }

  if (mapping_found) {
    request_header->mark_target_dirty();
  } else {
    Dbg(dbg_ctl_url_rewrite, "RemapProcessor::setup_for_remap did not find a mapping");
  }

  return mapping_found;
}

bool
RemapProcessor::finish_remap(HttpTransact::State *s, UrlRewrite *table)
{
  url_mapping  *map            = nullptr;
  HTTPHdr      *request_header = &s->hdr_info.client_request;
  URL          *request_url    = request_header->url_get();
  char        **redirect_url   = &s->remap_redirect;
  char          tmp_referer_buf[4096], tmp_redirect_buf[4096], tmp_buf[2048];
  int           tmp;
  int           from_len;
  referer_info *ri;

  map = s->url_map.getMapping();
  if (nullptr == map) {
    Dbg(dbg_ctl_url_rewrite, "Could not find corresponding url_mapping for this transaction");
    return false;
  }

  // Pass the volume_host_rec to the transaction state
  s->cache_info.volume_host_rec = map->getVolumeHostRec();

  // Do fast ACL filtering (it is safe to check map here)
  table->PerformACLFiltering(s, map);

  // Check referer filtering rules
  if ((s->filter_mask & URL_REMAP_FILTER_REFERER) != 0 && (ri = map->referer_list) != nullptr) {
    std::string_view referer_hdr{};
    bool             enabled_flag = map->optional_referer ? true : false;

    if (request_header->presence(MIME_PRESENCE_REFERER) &&
        !(referer_hdr = request_header->value_get(static_cast<std::string_view>(MIME_FIELD_REFERER))).empty()) {
      referer_hdr = referer_hdr.substr(0, std::min(referer_hdr.length(), sizeof(tmp_referer_buf) - 1));
      memcpy(tmp_referer_buf, referer_hdr.data(), referer_hdr.length());
      tmp_referer_buf[referer_hdr.length()] = 0;
      for (enabled_flag = false; ri; ri = ri->next) {
        if (ri->any) {
          enabled_flag = true;
          if (!map->negative_referer) {
            break;
          }
        } else if (ri->regex_valid && ri->regex.exec(std::string_view(tmp_referer_buf, referer_hdr.length()))) {
          enabled_flag = ri->negative ? false : true;
          break;
        }
      }
    }

    if (!enabled_flag) {
      if (!map->default_redirect_url) {
        if ((s->filter_mask & URL_REMAP_FILTER_REDIRECT_FMT) != 0 && map->redir_chunk_list) {
          redirect_tag_str *rc;
          tmp_redirect_buf[(tmp = 0)] = 0;

          for (rc = map->redir_chunk_list; rc; rc = rc->next) {
            char *c = nullptr;
            switch (rc->type) {
            case 's':
              c = rc->chunk_str;
              break;
            case 'r':
              c = (referer_hdr.empty() ? nullptr : &tmp_referer_buf[0]);
              break;
            case 'f':
            case 't':
              if (auto remapped_host_cstr =
                    (rc->type == 'f') ?
                      map->fromURL.string_get_buf(tmp_buf, static_cast<int>(sizeof(tmp_buf)), &from_len) :
                      ((s->url_map).getToURL())->string_get_buf(tmp_buf, static_cast<int>(sizeof(tmp_buf)), &from_len);
                  remapped_host_cstr && from_len > 0) {
                c = &tmp_buf[0];
              }
              break;
            case 'o':
              c = s->unmapped_url.string_get_ref(nullptr);
              break;
            };

            if (c && tmp < static_cast<int>(sizeof(tmp_redirect_buf) - 1)) {
              tmp += snprintf(&tmp_redirect_buf[tmp], sizeof(tmp_redirect_buf) - tmp, "%s", c);
            }
          }
          tmp_redirect_buf[sizeof(tmp_redirect_buf) - 1] = 0;
          *redirect_url                                  = ats_strdup(tmp_redirect_buf);
        }
      } else {
        *redirect_url = ats_strdup(table->http_default_redirect_url);
      }

      if (*redirect_url == nullptr) {
        *redirect_url = ats_strdup(map->filter_redirect_url ? map->filter_redirect_url : table->http_default_redirect_url);
      }
      if (HTTPStatus::NONE == s->http_return_code) {
        s->http_return_code = HTTPStatus::MOVED_TEMPORARILY;
      }
      return false;
    }
  }

  // We also need to rewrite the "Host:" header if it exists and
  //   pristine host hdr is not enabled

  if (auto host_hdr{request_header->value_get(static_cast<std::string_view>(MIME_FIELD_HOST))};
      request_url && !host_hdr.empty() && s->txn_conf->maintain_pristine_host_hdr == 0) {
    if (dbg_ctl_url_rewrite.on()) {
      auto old_host_hdr{request_header->value_get(static_cast<std::string_view>(MIME_FIELD_HOST))};
      if (!old_host_hdr.empty()) {
        Dbg(dbg_ctl_url_rewrite, "Host: Header before rewrite %.*s", static_cast<int>(old_host_hdr.length()), old_host_hdr.data());
      }
    }
    //
    // Create the new host header field being careful that our
    //   temporary buffer has adequate length
    //
    auto remapped_host{request_url->host_get()};
    auto remapped_host_len{static_cast<int>(remapped_host.length())};

    int remapped_port = request_url->port_get_raw();

    char host_hdr_buf[TS_MAX_HOST_NAME_LEN];
    if (TS_MAX_HOST_NAME_LEN > remapped_host_len) {
      tmp = remapped_host_len;
      memcpy(host_hdr_buf, remapped_host.data(), remapped_host_len);
      if (remapped_port) {
        tmp += snprintf(host_hdr_buf + remapped_host_len, TS_MAX_HOST_NAME_LEN - remapped_host_len - 1, ":%d", remapped_port);
      }
    } else {
      tmp = TS_MAX_HOST_NAME_LEN;
    }

    // It is possible that the hostname is too long.  If it is punt,
    //   and remove the host header.  If it is too long the HostDB
    //   won't be able to resolve it and the request will not go
    //   through
    if (tmp >= TS_MAX_HOST_NAME_LEN) {
      request_header->field_delete(static_cast<std::string_view>(MIME_FIELD_HOST));
      Dbg(dbg_ctl_url_rewrite, "Host: Header too long after rewrite");
    } else {
      Dbg(dbg_ctl_url_rewrite, "Host: Header after rewrite %.*s", tmp, host_hdr_buf);
      request_header->value_set(static_cast<std::string_view>(MIME_FIELD_HOST),
                                std::string_view{host_hdr_buf, static_cast<std::string_view::size_type>(tmp)});
    }
  }

  request_header->mark_target_dirty();

  return true;
}

Action *
RemapProcessor::perform_remap(Continuation *cont, HttpTransact::State *s)
{
  Dbg(dbg_ctl_url_rewrite, "Beginning RemapProcessor::perform_remap");
  HTTPHdr       *request_header = &s->hdr_info.client_request;
  URL           *request_url    = request_header->url_get();
  url_mapping   *map            = s->url_map.getMapping();
  host_hdr_info *hh_info        = &(s->hh_info);

  if (nullptr == map) {
    Error("Could not find corresponding url_mapping for this transaction %p", s);
    Dbg(dbg_ctl_url_rewrite, "Could not find corresponding url_mapping for this transaction");
    ink_assert(!"this should never happen -- call setup_for_remap first");
    cont->handleEvent(EVENT_REMAP_ERROR, nullptr);
    return ACTION_RESULT_DONE;
  }

  // if there is a configured next hop strategy, make it available in the state.
  if (nullptr != map->strategy) {
    Dbg(dbg_ctl_url_rewrite, "Setting next-hop strategy to %s", map->strategy->strategy_name.c_str());
    s->next_hop_strategy = map->strategy;
  }

  RemapPlugins plugins(s, request_url, request_header, hh_info);

  while (!plugins.run_single_remap()) {
    ; // EMPTY
  }

  return ACTION_RESULT_DONE;
}
