/** @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 structurs 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 = (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 = (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 = (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("%d", producer.read_vio->ndone);
      } else {
        resp_add("%d", producer.bytes_read);
      }
      resp_end_column();

      // Col 4 - nbytes
      resp_begin_column();
      if (producer.alive && producer.read_vio) {
        resp_add("%d", 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("%d", consumer.write_vio->ndone);
      } else {
        resp_add("%d", consumer.bytes_written);
      }
      resp_end_column();

      // Col 4 - nbytes
      resp_begin_column();
      if (consumer.alive && consumer.write_vio) {
        resp_add("%d", 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("%d", 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", (unsigned int)sm->history[i].event);
    resp_end_column();

    resp_begin_column();
    resp_add("%d", (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();
  }
}
