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

/**
 * @file GlobalPlugin.cc
 */
#include "tscpp/api/GlobalPlugin.h"
#include "ts/ts.h"
#include <cstddef>
#include <cassert>
#include "tscpp/api/noncopyable.h"
#include "utils_internal.h"
#include "logging_internal.h"

using namespace atscppapi;

/**
 * @private
 */
struct atscppapi::GlobalPluginState : noncopyable {
  TSCont        cont_ = nullptr;
  GlobalPlugin *global_plugin_;
  bool          ignore_internal_transactions_;

  GlobalPluginState(GlobalPlugin *global_plugin, bool ignore_internal_transactions)
    : global_plugin_(global_plugin), ignore_internal_transactions_(ignore_internal_transactions)
  {
  }
};

namespace
{
static int
handleGlobalPluginEvents(TSCont cont, TSEvent event, void *edata)
{
  GlobalPluginState *state = static_cast<GlobalPluginState *>(TSContDataGet(cont));

  if (event == TS_EVENT_HTTP_SELECT_ALT) {
    TSHttpAltInfo alt = static_cast<TSHttpAltInfo>(edata);
    utils::internal::invokePluginForEvent(state->global_plugin_, alt, event);
    return 0;
  }

  TSHttpTxn txn = static_cast<TSHttpTxn>(edata);
  if (state->ignore_internal_transactions_ && TSHttpTxnIsInternal(txn)) {
    LOG_DEBUG("Ignoring event %d on internal transaction %p for global plugin %p", event, txn, state->global_plugin_);
    TSHttpTxnReenable(txn, TS_EVENT_HTTP_CONTINUE);
  } else {
    LOG_DEBUG("Invoking global plugin %p for event %d on transaction %p", state->global_plugin_, event, txn);
    utils::internal::invokePluginForEvent(state->global_plugin_, txn, event);
  }
  return 0;
}

} /* anonymous namespace */

GlobalPlugin::GlobalPlugin(bool ignore_internal_transactions)
{
  utils::internal::initTransactionManagement();
  state_        = std::make_unique<GlobalPluginState>(this, ignore_internal_transactions);
  TSMutex mutex = nullptr;
  state_->cont_ = TSContCreate(handleGlobalPluginEvents, mutex);
  TSContDataSet(state_->cont_, static_cast<void *>(state_.get()));
}

GlobalPlugin::~GlobalPlugin()
{
  TSContDestroy(state_->cont_);
}

void
GlobalPlugin::registerHook(Plugin::HookType hook_type)
{
  assert(hook_type != Plugin::HOOK_TXN_CLOSE);
  TSHttpHookID hook_id = utils::internal::convertInternalHookToTsHook(hook_type);
  TSHttpHookAdd(hook_id, state_->cont_);
  LOG_DEBUG("Registered global plugin %p for hook %s", this, HOOK_TYPE_STRINGS[hook_type].c_str());
}
