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

/****************************************************************************

   HttpPages.cc

   Description:
       Data structures and stat page generators for http info


 ****************************************************************************/
#include "HttpPages.h"
#include "HttpSM.h"
#include "HttpDebugNames.h"

HttpSMListBucket HttpSMList[HTTP_LIST_BUCKETS];

HttpPagesHandler::HttpPagesHandler(Continuation *cont, HTTPHdr *header)
  : BaseStatPagesHandler(new_ProxyMutex()), request(nullptr), list_bucket(0), state(HP_INIT), sm_id(0)
{
  action = cont;

  URL *url;
  int length;

  url     = header->url_get();
  request = const_cast<char *>(url->path_get(&length));
  request = arena.str_store(request, length);

  if (strncmp(request, "sm_details", sizeof("sm_details")) == 0) {
    arena.str_free(request);
    request = const_cast<char *>(url->query_get(&length));
    request = arena.str_store(request, length);
    SET_HANDLER(&HttpPagesHandler::handle_smdetails);

  } else {
    SET_HANDLER(&HttpPagesHandler::handle_smlist);
  }
}

HttpPagesHandler::~HttpPagesHandler() {}

int64_t
HttpPagesHandler::extract_id(const char *query)
{
  char *p;
  int64_t id;

  p = const_cast<char *>(strstr(query, "id="));
  if (!p) {
    return -1;
  }
  p += sizeof("id=") - 1;

  id = ink_atoi64(p);

  // Check to see if we found the id
  if (id == 0) {
    if (*p == '0' && *(p + 1) == '\0') {
      return 0;
    } else {
      return -1;
    }
  } else {
    return id;
  }
}

void
HttpPagesHandler::dump_hdr(HTTPHdr *hdr, const char *desc)
{
  if (hdr->valid()) {
    resp_add("<h4> %s </h4>\n<pre>\n", desc);
    char b[4096];
    int used, tmp, offset;
    int done;
    offset = 0;
    do {
      used = 0;
      tmp  = offset;
      done = hdr->print(b, 4095, &used, &tmp);
      offset += used;
      b[used] = '\0';
      resp_add(b);
    } while (!done);
    resp_add("</pre>\n");
  }
}

void
HttpPagesHandler::dump_tunnel_info(HttpSM *sm)
{
  HttpTunnel *t = sm->get_tunnel();

  resp_add("<h4> Tunneling Info </h4>");

  resp_add("<p> Producers </p>");
  resp_begin_table(1, 4, 60);
  for (auto &producer : t->producers) {
    if (producer.vc != nullptr) {
      resp_begin_row();

      // Col 1 - name
      resp_begin_column();
      resp_add(producer.name);
      resp_end_column();

      // Col 2 - alive
      resp_begin_column();
      resp_add("%d", producer.alive);
      resp_end_column();

      // Col 3 - ndone
      resp_begin_column();
      if (producer.alive && producer.read_vio) {
        resp_add("%" PRId64, producer.read_vio->ndone);
      } else {
        resp_add("%" PRId64, producer.bytes_read);
      }
      resp_end_column();

      // Col 4 - nbytes
      resp_begin_column();
      if (producer.alive && producer.read_vio) {
        resp_add("%" PRId64, producer.read_vio->nbytes);
      } else {
        resp_add("-");
      }
      resp_end_column();

      resp_end_row();
    }
  }
  resp_end_table();

  resp_add("<p> Consumers </p>");
  resp_begin_table(1, 5, 60);
  for (auto &consumer : t->consumers) {
    if (consumer.vc != nullptr) {
      resp_begin_row();

      // Col 1 - name
      resp_begin_column();
      resp_add(consumer.name);
      resp_end_column();

      // Col 2 - alive
      resp_begin_column();
      resp_add("%d", consumer.alive);
      resp_end_column();

      // Col 3 - ndone
      resp_begin_column();
      if (consumer.alive && consumer.write_vio) {
        resp_add("%" PRId64, consumer.write_vio->ndone);
      } else {
        resp_add("%" PRId64, consumer.bytes_written);
      }
      resp_end_column();

      // Col 4 - nbytes
      resp_begin_column();
      if (consumer.alive && consumer.write_vio) {
        resp_add("%" PRId64, consumer.write_vio->nbytes);
      } else {
        resp_add("-");
      }
      resp_end_column();

      // Col 5 - read avail
      resp_begin_column();
      if (consumer.alive && consumer.buffer_reader) {
        resp_add("%" PRId64, consumer.buffer_reader->read_avail());
      } else {
        resp_add("-");
      }
      resp_end_column();

      resp_end_row();
    }
  }
  resp_end_table();
}

void
HttpPagesHandler::dump_history(HttpSM *sm)
{
  resp_add("<h4> History</h4>");
  resp_begin_table(1, 3, 60);

  // Figure out how big the history is and look
  //  for wrap around
  for (unsigned int i = 0; i < sm->history.size(); i++) {
    char buf[256];
    resp_begin_row();

    resp_begin_column();
    resp_add("%s", sm->history[i].location.str(buf, sizeof(buf)));
    resp_end_column();

    resp_begin_column();
    resp_add("%u", static_cast<unsigned int>(sm->history[i].event));
    resp_end_column();

    resp_begin_column();
    resp_add("%d", static_cast<int>(sm->history[i].reentrancy));
    resp_end_column();

    resp_end_row();
  }

  resp_end_table();
}

int
HttpPagesHandler::dump_sm(HttpSM *sm)
{
  // Dump the current state
  const char *sm_state = HttpDebugNames::get_action_name(sm->t_state.next_action);

  resp_begin_item();
  resp_add("Current State: %s", sm_state);
  resp_end_item();

  dump_hdr(&sm->t_state.hdr_info.client_request, "Client Request");
  dump_hdr(&sm->t_state.hdr_info.server_request, "Server Request");
  dump_hdr(&sm->t_state.hdr_info.server_response, "Server Response");
  dump_hdr(&sm->t_state.hdr_info.client_response, "Client Response");

  dump_tunnel_info(sm);
  dump_history(sm);

  return EVENT_DONE;
}

int
HttpPagesHandler::handle_smdetails(int event, void * /* data ATS_UNUSED */)
{
  EThread *ethread = this_ethread();
  HttpSM *sm       = nullptr;

  switch (event) {
  case EVENT_NONE:
  case EVENT_INTERVAL:
  case EVENT_IMMEDIATE:
    break;
  default:
    ink_assert(0);
    break;
  }

  // Do initial setup if necessary
  if (state == HP_INIT) {
    state = HP_RUN;

    // Get our SM id
    sm_id = extract_id(request);

    if (sm_id < 0) {
      resp_begin("Http Pages Error");
      resp_add("<b>Unable to extract id</b>\n");
      resp_end();
      return handle_callback(EVENT_NONE, nullptr);
    }

    resp_begin("Http:SM Details");
    resp_begin_item();
    resp_add("Details for SM id  %" PRId64 "", sm_id);
    resp_end_item();
  }

  for (; list_bucket < HTTP_LIST_BUCKETS; list_bucket++) {
    MUTEX_TRY_LOCK(lock, HttpSMList[list_bucket].mutex, ethread);

    if (!lock.is_locked()) {
      eventProcessor.schedule_in(this, HTTP_LIST_RETRY, ET_CALL);
      return EVENT_DONE;
    }

    sm = HttpSMList[list_bucket].sm_list.head;

    while (sm != nullptr) {
      if (sm->sm_id == sm_id) {
        // In this block we try to get the lock of the
        //   state machine
        {
          MUTEX_TRY_LOCK(sm_lock, sm->mutex, ethread);
          if (sm_lock.is_locked()) {
            dump_sm(sm);
            resp_end();
            return handle_callback(EVENT_NONE, nullptr);
          } else {
            // We missed the lock so retry
            eventProcessor.schedule_in(this, HTTP_LIST_RETRY, ET_CALL);
            return EVENT_DONE;
          }
        }
      }

      sm = sm->debug_link.next;
    }
  }

  // If we got here, we did not find our state machine
  resp_add("<h2>Id %" PRId64 " not found</h2>", sm_id);
  resp_end();
  return handle_callback(EVENT_NONE, nullptr);
}

int
HttpPagesHandler::handle_smlist(int event, void * /* data ATS_UNUSED */)
{
  EThread *ethread = this_ethread();
  HttpSM *sm;

  switch (event) {
  case EVENT_NONE:
  case EVENT_INTERVAL:
  case EVENT_IMMEDIATE:
    break;
  default:
    ink_assert(0);
    break;
  }

  if (state == HP_INIT) {
    resp_begin("Http:SM List");
    state = HP_RUN;
  }

  for (; list_bucket < HTTP_LIST_BUCKETS; list_bucket++) {
    MUTEX_TRY_LOCK(lock, HttpSMList[list_bucket].mutex, ethread);

    if (!lock.is_locked()) {
      eventProcessor.schedule_in(this, HTTP_LIST_RETRY, ET_CALL);
      return EVENT_DONE;
    }

    sm = HttpSMList[list_bucket].sm_list.head;

    while (sm != nullptr) {
      char *url          = nullptr;
      const char *method = nullptr;
      int method_len;
      const char *sm_state = nullptr;

      // In this block we try to get the lock of the
      //   state machine
      {
        MUTEX_TRY_LOCK(sm_lock, sm->mutex, ethread);
        if (sm_lock.is_locked()) {
          if (sm->t_state.hdr_info.client_request.valid()) {
            sm_state = HttpDebugNames::get_action_name(sm->t_state.next_action);

            method = sm->t_state.hdr_info.client_request.method_get(&method_len);
            method = arena.str_store(method, method_len);
            URL *u = sm->t_state.hdr_info.client_request.url_get();
            if (u->valid()) {
              url = u->string_get(&arena);
            }
          }

          if (url == nullptr) {
            url      = arena.str_store("-", 1);
            sm_state = "READ_REQUEST";
          }
        } else {
          url      = arena.str_store("-", 1);
          sm_state = "LOCKED";
        }
      }

      resp_begin_item();
      resp_add("id: <a href=\"./sm_details?id=%" PRId64 "\"> %" PRId64 " </a> | %s %s | %s\n", sm->sm_id, sm->sm_id,
               method ? method : "", url, sm_state ? sm_state : "");
      resp_end_item();
      arena.str_free(url);

      sm = sm->debug_link.next;
    }
  }

  resp_end();
  handle_callback(EVENT_NONE, nullptr);

  return EVENT_DONE;
}

int
HttpPagesHandler::handle_callback(int /* event ATS_UNUSED */, void * /* edata ATS_UNUSED */)
{
  MUTEX_TRY_LOCK(trylock, action.mutex, this_ethread());
  if (!trylock.is_locked()) {
    SET_HANDLER(&HttpPagesHandler::handle_callback);
    eventProcessor.schedule_in(this, HTTP_LIST_RETRY, ET_CALL);
    return EVENT_DONE;
  }

  if (!action.cancelled) {
    if (response) {
      StatPageData data;

      data.data   = response;
      data.type   = ats_strdup("text/html");
      data.length = response_length;
      response    = nullptr;

      action.continuation->handleEvent(STAT_PAGE_SUCCESS, &data);
    } else {
      action.continuation->handleEvent(STAT_PAGE_FAILURE, nullptr);
    }
  }

  delete this;
  return EVENT_DONE;
}

static Action *
http_pages_callback(Continuation *cont, HTTPHdr *header)
{
  HttpPagesHandler *handler;

  handler = new HttpPagesHandler(cont, header);
  eventProcessor.schedule_imm(handler, ET_CALL);

  return &handler->action;
}

void
http_pages_init()
{
  statPagesManager.register_http("http", http_pages_callback);

  // Create the mutexes for http list protection
  for (auto &i : HttpSMList) {
    i.mutex = new_ProxyMutex();
  }
}
