/** @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/HttpCacheSM.h"
#include "iocore/eventsystem/Thread.h"
#include "proxy/http/HttpSM.h"
#include "proxy/http/HttpDebugNames.h"

#include "iocore/cache/Cache.h"
#include "tscore/ink_assert.h"

#define SM_REMEMBER(sm, e, r)                          \
  {                                                    \
    sm->history.push_back(MakeSourceLocation(), e, r); \
  }

#define STATE_ENTER(state_name, event)                                                                                       \
  {                                                                                                                          \
    SM_REMEMBER(master_sm, event, NO_REENTRANT);                                                                             \
    Dbg(dbg_ctl_http_cache, "[%" PRId64 "] [%s, %s]", master_sm->sm_id, #state_name, HttpDebugNames::get_event_name(event)); \
  }

namespace
{
DbgCtl dbg_ctl_http_cache{"http_cache"};
} // end anonymous namespace

////
// HttpCacheAction
//
void
HttpCacheAction::cancel(Continuation *c)
{
  ink_assert(c == nullptr || c == _cache_sm->master_sm);
  ink_assert(this->cancelled == false);

  this->cancelled = true;
  _cache_sm->cancel_pending_action();
}

////
// HttpCacheSM
//
/**
  Reset state for another cache operation (e.g., following a redirect).

  This closes any existing cache read VC, cancels pending retry events,
  and resets the captive action. Without this cleanup, a stale cache_read_vc
  from a previous successful read could remain set when the new cache
  operation completes, causing an assertion failure if redirect_in_process
  has been cleared by that time.
 */
void
HttpCacheSM::reset()
{
  captive_action.reset();
  close_read();

  if (_read_retry_event != nullptr) {
    _read_retry_event->cancel();
    _read_retry_event = nullptr;
  }
}

void
HttpCacheSM::cancel_pending_action()
{
  if (pending_action != nullptr) {
    pending_action->cancel();
    pending_action = nullptr;
  }

  if (_read_retry_event != nullptr) {
    _read_retry_event->cancel();
    _read_retry_event = nullptr;
  }
}

//////////////////////////////////////////////////////////////////////////
//
//  HttpCacheSM::state_cache_open_read()
//
//  State the cache calls back the state machine into on a open_read
//  call. The set of allowed events (from the cache) are:
// - CACHE_EVENT_OPEN_READ
//   - document matching request is in the cache
// - CACHE_EVENT_OPEN_READ_FAILED
//   if (data != ECACHEDOCBUSY)
//   - document matching request is not in the cache
//   if (data == ECACHEDOCBUSY)
//   - document with same URL as request is in the cache
//     but is being currently updated by another state
//     machine. Keep in mind that the document may NOT
//     match any of the request headers - it just matches
//     the URL. In other words, the document that is being
//     written to by another state machine may be an
//     alternate of the document the request wants.
// - EVENT_INTERVAL
//   - a previous open_read returned "failed_in_progress". we
//     decided to retry the open read. we scheduled the event
//     processor to call us back after n msecs so that we can
//     reissue the open_read. this is the call from the event
//     processor.
//
//////////////////////////////////////////////////////////////////////////
int
HttpCacheSM::state_cache_open_read(int event, void *data)
{
  STATE_ENTER(&HttpCacheSM::state_cache_open_read, event);
  ink_assert(captive_action.cancelled == 0);
  pending_action = nullptr;

  if (captive_action.cancelled == 1) {
    return VC_EVENT_CONT; // SM gave up on us
  }

  switch (event) {
  case CACHE_EVENT_OPEN_READ:
    Metrics::Gauge::increment(http_rsb.current_cache_connections);
    ink_assert((cache_read_vc == nullptr) || master_sm->t_state.redirect_info.redirect_in_process ||
               master_sm->t_state.cache_info.write_lock_state == HttpTransact::CacheWriteLock_t::READ_RETRY);
    if (cache_read_vc) {
      // A redirect follow or a read retry after losing the cache write lock
      // replaces the read VC. The stale object that a read retry saved as its
      // fallback lives in the VC being closed, so it cannot outlive it.
      master_sm->t_state.cache_info.stale_fallback = nullptr;
      close_read();
    }
    cache_read_vc = static_cast<CacheVConnection *>(data);
    master_sm->handleEvent(event, &captive_action);
    break;

  case CACHE_EVENT_OPEN_READ_RWW:
    set_readwhilewrite_inprogress(true);
    break;

  case CACHE_EVENT_OPEN_READ_FAILED:
    err_code = reinterpret_cast<intptr_t>(data);
    if ((intptr_t)data == -ECACHE_DOC_BUSY) {
      // Somebody else is writing the object
      if (open_read_tries <= master_sm->t_state.txn_conf->max_cache_open_read_retries) {
        // Retry to read; maybe the update finishes in time
        _schedule_read_retry();
      } else {
        // Give up; the update didn't finish in time
        // HttpSM will inform HttpTransact to 'proxy-only'
        master_sm->handleEvent(event, &captive_action);
      }
    } else {
      // Simple miss in the cache.
      master_sm->handleEvent(event, &captive_action);
    }
    break;

  case EVENT_INTERVAL:
    if (_read_retry_event == static_cast<Event *>(data)) {
      _read_retry_event = nullptr;
    }

    // Retry the cache open read if the number retries is less
    // than or equal to the max number of open read retries,
    // else treat as a cache miss.
    ink_assert(open_read_tries <= master_sm->t_state.txn_conf->max_cache_open_read_retries);
    Dbg(dbg_ctl_http_cache,
        "[%" PRId64 "] [state_cache_open_read] cache open read failure %d. "
        "retrying cache open read...",
        master_sm->sm_id, open_read_tries);

    do_cache_open_read(cache_key);
    break;

  default:
    ink_assert(0);
  }

  return VC_EVENT_CONT;
}

bool
HttpCacheSM::write_retry_done() const
{
  MgmtInt const timeout_ms = master_sm->t_state.txn_conf->max_cache_open_write_retry_timeout;
  if (0 < timeout_ms && 0 < open_write_start) {
    ink_hrtime const elapsed = ink_get_hrtime() - open_write_start;
    MgmtInt const    msecs   = ink_hrtime_to_msec(elapsed);
    return timeout_ms < msecs;
  } else {
    return master_sm->t_state.txn_conf->max_cache_open_write_retries < open_write_tries;
  }
}

int
HttpCacheSM::state_cache_open_write(int event, void *data)
{
  STATE_ENTER(&HttpCacheSM::state_cache_open_write, event);
  ink_assert(captive_action.cancelled == 0);
  pending_action = nullptr;

  if (captive_action.cancelled == 1) {
    return VC_EVENT_CONT; // SM gave up on us
  }
  bool read_retry_on_write_fail = false;

  switch (event) {
  case CACHE_EVENT_OPEN_WRITE:
    Metrics::Gauge::increment(http_rsb.current_cache_connections);
    ink_assert(cache_write_vc == nullptr);
    cache_write_vc = static_cast<CacheVConnection *>(data);
    master_sm->handleEvent(event, &captive_action);
    break;

  case CACHE_EVENT_OPEN_WRITE_FAILED: {
    if (is_read_retry_write_fail_action(master_sm->t_state.txn_conf->cache_open_write_fail_action)) {
      // fall back to open_read_tries
      // Note that when READ_RETRY actions are configured, max_cache_open_write_retries
      // is automatically ignored. Make sure to not disable max_cache_open_read_retries
      // with READ_RETRY actions as this results in proxy'ing to origin
      // without write retries in both a cache miss or a cache refresh scenario.

      if (write_retry_done()) {
        Dbg(dbg_ctl_http_cache, "[%" PRId64 "] [state_cache_open_write] cache open write failure %d. read retry triggered",
            master_sm->sm_id, open_write_tries);
        if (master_sm->t_state.txn_conf->max_cache_open_read_retries <= 0) {
          Dbg(dbg_ctl_http_cache,
              "[%" PRId64 "] [state_cache_open_write] invalid config, cache write fail set to"
              " read retry, but, max_cache_open_read_retries is not enabled",
              master_sm->sm_id);
        }
        open_read_tries = 0;

        read_retry_on_write_fail = true;
        // make sure it doesn't loop indefinitely
        open_write_tries            = master_sm->t_state.txn_conf->max_cache_open_write_retries + 1;
        MgmtInt const retry_timeout = master_sm->t_state.txn_conf->max_cache_open_write_retry_timeout;
        if (0 < retry_timeout) {
          open_write_start = ink_get_hrtime() - ink_hrtime_from_msec(retry_timeout);
        }
      }
    }

    if (read_retry_on_write_fail || !write_retry_done()) {
      // Retry open read;
      _schedule_read_retry();
    } else {
      // The cache is hosed or full or something.
      // Forward the failure to the main sm
      Dbg(dbg_ctl_http_cache,
          "[%" PRId64 "] [state_cache_open_write] cache open write failure %d. "
          "done retrying...",
          master_sm->sm_id, open_write_tries);
      err_code = reinterpret_cast<intptr_t>(data);
      master_sm->handleEvent(event, &captive_action);
    }
  } break;

  case EVENT_INTERVAL:
    if (_read_retry_event == static_cast<Event *>(data)) {
      _read_retry_event = nullptr;
    }

    if (is_read_retry_write_fail_action(master_sm->t_state.txn_conf->cache_open_write_fail_action)) {
      Dbg(dbg_ctl_http_cache,
          "[%" PRId64 "] [state_cache_open_write] cache open write failure %d. "
          "falling back to read retry...",
          master_sm->sm_id, open_write_tries);
      master_sm->handleEvent(CACHE_EVENT_OPEN_READ, &captive_action);
    } else {
      Dbg(dbg_ctl_http_cache,
          "[%" PRId64 "] [state_cache_open_write] cache open write failure %d. "
          "retrying cache open write...",
          master_sm->sm_id, open_write_tries);

      // Retry the cache open write if the number retries is less
      // than or equal to the max number of open write retries
      ink_assert(!write_retry_done());

      open_write(&cache_key, lookup_url, read_request_hdr,
                 CompatCacheKey::write_info(master_sm->compatibility_cache_lookup, master_sm->t_state.cache_info.object_read),
                 static_cast<time_t>(
                   (master_sm->t_state.cache_control.pin_in_cache_for < 0) ? 0 : master_sm->t_state.cache_control.pin_in_cache_for),
                 retry_write, false);
    }
    break;

  default:
    ink_release_assert(0);
  }

  return VC_EVENT_CONT;
}

/**
  Schedule a read retry event to this HttpCacheSM continuation with cache_open_read_retry_time delay.
  The scheduled event is tracked by `_read_retry_event`.
 */
void
HttpCacheSM::_schedule_read_retry()
{
  ink_release_assert(this->mutex->thread_holding == this_ethread());

  if (_read_retry_event != nullptr && _read_retry_event->cancelled == false) {
    _read_retry_event->cancel();
  }

  _read_retry_event =
    mutex->thread_holding->schedule_in(this, HRTIME_MSECONDS(master_sm->t_state.txn_conf->cache_open_read_retry_time));

  return;
}

Action *
HttpCacheSM::do_cache_open_read(const HttpCacheKey &key)
{
  Action *action_handle = nullptr;

  open_read_tries++;
  ink_assert(pending_action == nullptr);

  // Initialising read-while-write-inprogress flag
  this->readwhilewrite_inprogress = false;

  if (master_sm && master_sm->t_state.cache_info.volume_host_rec) {
    action_handle = cacheProcessor.open_read(this, &key, this->read_request_hdr, &http_params, CACHE_FRAG_TYPE_HTTP,
                                             master_sm->t_state.cache_info.volume_host_rec);
  } else {
    action_handle = cacheProcessor.open_read(this, &key, this->read_request_hdr, &http_params);
  }

  if (action_handle != ACTION_RESULT_DONE) {
    pending_action           = action_handle;
    captive_action.cancelled = false; // Make sure not cancelled before we hand it out
    return &captive_action;
  } else {
    // In some cases, CacheProcessor::open_read calls back to `state_cache_open_read` with a cache event. If the event is
    // CACHE_EVENT_OPEN_READ_FAILED, a read retry event might be scheduled. In this case, CacheProcessor::open_read returns
    // ACTION_RESULT_DONE, even though the read retry event is still pending. To indicate this situation to HttpSM, `captive_action`
    // is returned. HttpSM can cancel the event though this `captive_action` if necessary.
    if (_read_retry_event && _read_retry_event->cancelled != true) {
      captive_action.cancelled = false;
      return &captive_action;
    } else {
      return ACTION_RESULT_DONE;
    }
  }
}

Action *
HttpCacheSM::open_read(const HttpCacheKey *key, URL *url, HTTPHdr *hdr, const OverridableHttpConfigParams *params,
                       time_t pin_in_cache)
{
  Action *act_return;

  cache_key         = *key;
  lookup_url        = url;
  read_request_hdr  = hdr;
  http_params       = params;
  read_pin_in_cache = pin_in_cache;
  ink_assert(pending_action == nullptr);
  SET_HANDLER(&HttpCacheSM::state_cache_open_read);

  lookup_max_recursive++;
  current_lookup_level++;
  act_return = do_cache_open_read(cache_key);
  // the following logic is based on the assumption that the second
  // lookup won't happen if the HttpSM hasn't been called back for the
  // first lookup
  if (current_lookup_level == lookup_max_recursive) {
    current_lookup_level--;
    ink_assert(current_lookup_level >= 0);
    if (current_lookup_level == 0) {
      lookup_max_recursive = 0;
    }
    return act_return;
  } else {
    ink_assert(current_lookup_level < lookup_max_recursive);
    current_lookup_level--;

    if (current_lookup_level == 0) {
      lookup_max_recursive = 0;
    }

    return ACTION_RESULT_DONE;
  }
}

Action *
HttpCacheSM::open_write(const HttpCacheKey *key, URL *url, HTTPHdr *request, CacheHTTPInfo *old_info, time_t pin_in_cache,
                        bool retry, bool allow_multiple)
{
  SET_HANDLER(&HttpCacheSM::state_cache_open_write);
  ink_assert(pending_action == nullptr);
  ink_assert((cache_write_vc == nullptr) || master_sm->t_state.redirect_info.redirect_in_process);

  open_write_tries++;
  if (0 == open_write_start) {
    open_write_start = ink_get_hrtime();
  }
  this->retry_write = retry;

  // We should be writing the same document we did
  //  a lookup on
  // this is no longer true for multiple cache lookup
  // ink_assert(url == lookup_url || lookup_url == NULL);
  ink_assert(request == read_request_hdr || read_request_hdr == nullptr);
  this->lookup_url       = url;
  this->read_request_hdr = request;
  cache_key              = *key;

  // Make sure we are not stuck in a loop where the write
  //  fails but the retry read succeeds causing to issue
  //  a new write (could happen on a very busy document
  //  that must be revalidated every time)
  // Changed by YTS Team, yamsat Plugin
  // two criteria, either write retries over the amount OR timeout
  if (open_write_tries > master_sm->redirection_tries && write_retry_done()) {
    err_code = -ECACHE_DOC_BUSY;
    master_sm->handleEvent(CACHE_EVENT_OPEN_WRITE_FAILED, &captive_action);
    return ACTION_RESULT_DONE;
  }

  CacheHTTPInfo *info          = allow_multiple ? reinterpret_cast<CacheHTTPInfo *>(CACHE_ALLOW_MULTIPLE_WRITES) : old_info;
  Action        *action_handle = nullptr;

  if (master_sm->t_state.cache_info.volume_host_rec) {
    action_handle =
      cacheProcessor.open_write(this, key, info, pin_in_cache, CACHE_FRAG_TYPE_HTTP, master_sm->t_state.cache_info.volume_host_rec);
  } else {
    action_handle = cacheProcessor.open_write(this, key, info, pin_in_cache);
  }

  if (action_handle != ACTION_RESULT_DONE) {
    pending_action           = action_handle;
    captive_action.cancelled = false; // Make sure not cancelled before we hand it out
    return &captive_action;
  } else {
    // In some cases, CacheProcessor::open_write calls back to `state_cache_open_write` with a cache event. If the event is
    // CACHE_EVENT_OPEN_WRITE_FAILED, a read retry event might be scheduled. In this case, CacheProcessor::open_write returns
    // ACTION_RESULT_DONE, even though the read retry event is still pending. To indicate this situation to HttpSM, `captive_action`
    // is returned. HttpSM can cancel the event though this `captive_action` if necessary.
    if (_read_retry_event && _read_retry_event->cancelled != true) {
      captive_action.cancelled = false;
      return &captive_action;
    } else {
      return ACTION_RESULT_DONE;
    }
  }
}
