/** @file

  Internal SDK stuff

  @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 "ts/apidefs.h"
#include "ts/InkAPIPrivateIOCore.h"

#include "tscore/Allocator.h"
#include "tscore/Diags.h"
#include "tscore/ink_assert.h"
#include "tscore/ink_atomic.h"

// http_remap
#include "proxy/http/remap/RemapPluginInfo.h"

// inkevent
#include "iocore/eventsystem/Continuation.h"
#include "iocore/eventsystem/EThread.h"
#include "iocore/eventsystem/Event.h"
#include "iocore/eventsystem/Lock.h"
#include "iocore/eventsystem/ProxyAllocator.h"
#include "iocore/eventsystem/VConnection.h"

ClassAllocator<INKContInternal, false> INKContAllocator("INKContAllocator");

namespace
{

DbgCtl dbg_ctl_plugin{"plugin"};

} // end anonymous namespace

INKContInternal::INKContInternal()
  : DummyVConnection(nullptr),
    mdata(nullptr),
    m_event_func(nullptr),
    m_event_count(0),
    m_closed(1),
    m_deletable(0),
    m_deleted(0),
    m_context(0),
    m_free_magic(INKCONT_INTERN_MAGIC_ALIVE)
{
}

INKContInternal::INKContInternal(TSEventFunc funcp, TSMutex mutexp)
  : DummyVConnection((ProxyMutex *)mutexp),
    mdata(nullptr),
    m_event_func(funcp),
    m_event_count(0),
    m_closed(1),
    m_deletable(0),
    m_deleted(0),
    m_context(0),
    m_free_magic(INKCONT_INTERN_MAGIC_ALIVE)
{
  SET_HANDLER(&INKContInternal::handle_event);
}

void
INKContInternal::init(TSEventFunc funcp, TSMutex mutexp, void *context)
{
  SET_HANDLER(&INKContInternal::handle_event);

  mutex        = (ProxyMutex *)mutexp;
  m_event_func = funcp;
  m_context    = context;
}

void
INKContInternal::clear()
{
}

void
INKContInternal::free()
{
  this->clear();
  this->mutex.clear();
  m_free_magic = INKCONT_INTERN_MAGIC_DEAD;
  THREAD_FREE(this, INKContAllocator, this_thread());
}

void
INKContInternal::destroy()
{
  if (m_free_magic == INKCONT_INTERN_MAGIC_DEAD) {
    ink_release_assert(!"Plugin tries to use a continuation which is deleted");
  }
  m_deleted = 1;
  if (m_deletable) {
    this->free();
  } else {
    // TODO: Should this schedule on some other "thread" ?
    // TODO: we don't care about the return action?
    if (ink_atomic_increment((int *)&m_event_count, 1) < 0) {
      ink_assert(!"not reached");
    }
    EThread *p = this_ethread();

    // If this_thread() returns null, the EThread object for the current thread has been destroyed (or it never existed).
    // Presumably this will only happen during destruction of statically-initialized objects at TS shutdown, so no further
    // action is needed.
    //
    if (p) {
      p->schedule_imm(this);
    }
  }
}

void
INKContInternal::handle_event_count(int event)
{
  if ((event == EVENT_IMMEDIATE) || (event == EVENT_INTERVAL) || event == TS_EVENT_HTTP_TXN_CLOSE) {
    int val = ink_atomic_increment((int *)&m_event_count, -1);
    if (val <= 0) {
      ink_assert(!"not reached");
    }

    m_deletable = (m_closed != 0) && (val == 1);
  }
}

int
INKContInternal::handle_event(int event, void *edata)
{
  if (m_free_magic == INKCONT_INTERN_MAGIC_DEAD) {
    ink_release_assert(!"Plugin tries to use a continuation which is deleted");
  }
  this->handle_event_count(event);
  if (m_deleted) {
    if (m_deletable) {
      this->free();
    } else {
      Dbg(dbg_ctl_plugin, "INKCont Deletable but not deleted %d", m_event_count);
    }
  } else {
    /* set the plugin context */
    auto *previousContext = pluginThreadContext;
    pluginThreadContext   = reinterpret_cast<PluginThreadContext *>(m_context);
    // Every TSCont (continuation) callback dispatch flows through here; count it against the owning
    // plugin. (Remap doRemap dispatch does not, and is counted in RemapPlugins::run_plugin instead.)
    if (pluginThreadContext != nullptr) {
      pluginThreadContext->countInvocation();
    }
    int retval          = m_event_func((TSCont)this, (TSEvent)event, edata);
    pluginThreadContext = previousContext;
    if (edata && event == EVENT_INTERVAL) {
      Event *e = reinterpret_cast<Event *>(edata);
      if (e->period != 0) {
        // In the interval case, we must re-increment the m_event_count for
        // the next go around.  Otherwise, our event count will go negative.
        ink_release_assert(ink_atomic_increment((int *)&this->m_event_count, 1) >= 0);
      }
    }
    return retval;
  }
  return EVENT_DONE;
}
