/*
  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_lua_hook.h"
#include "ts_lua_transform.h"
#include "ts_lua_util.h"

typedef enum {
  TS_LUA_HOOK_DUMMY = 0,
  TS_LUA_HOOK_CACHE_LOOKUP_COMPLETE,
  TS_LUA_HOOK_SEND_REQUEST_HDR,
  TS_LUA_HOOK_READ_RESPONSE_HDR,
  TS_LUA_HOOK_SEND_RESPONSE_HDR,
  TS_LUA_HOOK_READ_REQUEST_HDR,
  TS_LUA_HOOK_TXN_START,
  TS_LUA_HOOK_PRE_REMAP,
  TS_LUA_HOOK_POST_REMAP,
  TS_LUA_HOOK_OS_DNS,
  TS_LUA_HOOK_READ_CACHE_HDR,
  TS_LUA_HOOK_TXN_CLOSE,
  TS_LUA_REQUEST_TRANSFORM,
  TS_LUA_RESPONSE_TRANSFORM,
  TS_LUA_HOOK_LAST
} TSLuaHookID;

char *ts_lua_hook_id_string[] = {"TS_LUA_HOOK_DUMMY",
                                 "TS_LUA_HOOK_CACHE_LOOKUP_COMPLETE",
                                 "TS_LUA_HOOK_SEND_REQUEST_HDR",
                                 "TS_LUA_HOOK_READ_RESPONSE_HDR",
                                 "TS_LUA_HOOK_SEND_RESPONSE_HDR",
                                 "TS_LUA_HOOK_READ_REQUEST_HDR",
                                 "TS_LUA_HOOK_TXN_START",
                                 "TS_LUA_HOOK_PRE_REMAP",
                                 "TS_LUA_HOOK_POST_REMAP",
                                 "TS_LUA_HOOK_OS_DNS",
                                 "TS_LUA_HOOK_READ_CACHE_HDR",
                                 "TS_LUA_HOOK_TXN_CLOSE",
                                 "TS_LUA_REQUEST_TRANSFORM",
                                 "TS_LUA_RESPONSE_TRANSFORM",
                                 "TS_LUA_HOOK_LAST"};

static int ts_lua_add_hook(lua_State *L);
static void ts_lua_inject_hook_variables(lua_State *L);

void
ts_lua_inject_hook_api(lua_State *L)
{
  lua_pushcfunction(L, ts_lua_add_hook);
  lua_setfield(L, -2, "hook");

  ts_lua_inject_hook_variables(L);
}

static void
ts_lua_inject_hook_variables(lua_State *L)
{
  size_t i;

  for (i = 0; i < sizeof(ts_lua_hook_id_string) / sizeof(char *); i++) {
    lua_pushinteger(L, (lua_Integer)i);
    lua_setglobal(L, ts_lua_hook_id_string[i]);
  }
}

static int
ts_lua_add_hook(lua_State *L)
{
  int type;
  int entry;

  TSVConn connp;
  ts_lua_http_ctx *http_ctx;

  http_ctx = ts_lua_get_http_ctx(L);

  entry = lua_tointeger(L, 1); // get hook id

  type = lua_type(L, 2);
  if (type != LUA_TFUNCTION)
    return 0;

  switch (entry) {
  case TS_LUA_HOOK_CACHE_LOOKUP_COMPLETE:
    if (http_ctx) {
      TSHttpTxnHookAdd(http_ctx->txnp, TS_HTTP_CACHE_LOOKUP_COMPLETE_HOOK, http_ctx->cinfo.contp);
      http_ctx->has_hook = 1;
      lua_pushvalue(L, 2);
      lua_setglobal(L, TS_LUA_FUNCTION_CACHE_LOOKUP_COMPLETE);
    } else {
      lua_pushvalue(L, 2);
      lua_setglobal(L, TS_LUA_FUNCTION_G_CACHE_LOOKUP_COMPLETE);
    }
    break;

  case TS_LUA_HOOK_SEND_REQUEST_HDR:
    if (http_ctx) {
      TSHttpTxnHookAdd(http_ctx->txnp, TS_HTTP_SEND_REQUEST_HDR_HOOK, http_ctx->cinfo.contp);
      http_ctx->has_hook = 1;
      lua_pushvalue(L, 2);
      lua_setglobal(L, TS_LUA_FUNCTION_SEND_REQUEST);
    } else {
      lua_pushvalue(L, 2);
      lua_setglobal(L, TS_LUA_FUNCTION_G_SEND_REQUEST);
    }
    break;

  case TS_LUA_HOOK_READ_RESPONSE_HDR:
    if (http_ctx) {
      TSHttpTxnHookAdd(http_ctx->txnp, TS_HTTP_READ_RESPONSE_HDR_HOOK, http_ctx->cinfo.contp);
      http_ctx->has_hook = 1;
      lua_pushvalue(L, 2);
      lua_setglobal(L, TS_LUA_FUNCTION_READ_RESPONSE);
    } else {
      lua_pushvalue(L, 2);
      lua_setglobal(L, TS_LUA_FUNCTION_G_READ_RESPONSE);
    }
    break;

  case TS_LUA_HOOK_SEND_RESPONSE_HDR:
    if (http_ctx) {
      TSHttpTxnHookAdd(http_ctx->txnp, TS_HTTP_SEND_RESPONSE_HDR_HOOK, http_ctx->cinfo.contp);
      http_ctx->has_hook = 1;
      lua_pushvalue(L, 2);
      lua_setglobal(L, TS_LUA_FUNCTION_SEND_RESPONSE);
    } else {
      lua_pushvalue(L, 2);
      lua_setglobal(L, TS_LUA_FUNCTION_G_SEND_RESPONSE);
    }
    break;

  case TS_LUA_HOOK_READ_REQUEST_HDR:
    if (http_ctx) {
      TSHttpTxnHookAdd(http_ctx->txnp, TS_HTTP_READ_REQUEST_HDR_HOOK, http_ctx->cinfo.contp);
      http_ctx->has_hook = 1;
      lua_pushvalue(L, 2);
      lua_setglobal(L, TS_LUA_FUNCTION_READ_REQUEST);
    } else {
      lua_pushvalue(L, 2);
      lua_setglobal(L, TS_LUA_FUNCTION_G_READ_REQUEST);
    }
    break;

  case TS_LUA_HOOK_TXN_START:
    if (http_ctx) {
      TSHttpTxnHookAdd(http_ctx->txnp, TS_HTTP_TXN_START_HOOK, http_ctx->cinfo.contp);
      http_ctx->has_hook = 1;
      lua_pushvalue(L, 2);
      lua_setglobal(L, TS_LUA_FUNCTION_TXN_START);
    } else {
      lua_pushvalue(L, 2);
      lua_setglobal(L, TS_LUA_FUNCTION_G_TXN_START);
    }
    break;

  case TS_LUA_HOOK_PRE_REMAP:
    if (http_ctx) {
      TSHttpTxnHookAdd(http_ctx->txnp, TS_HTTP_PRE_REMAP_HOOK, http_ctx->cinfo.contp);
      http_ctx->has_hook = 1;
      lua_pushvalue(L, 2);
      lua_setglobal(L, TS_LUA_FUNCTION_PRE_REMAP);
    } else {
      lua_pushvalue(L, 2);
      lua_setglobal(L, TS_LUA_FUNCTION_G_PRE_REMAP);
    }
    break;

  case TS_LUA_HOOK_POST_REMAP:
    if (http_ctx) {
      TSHttpTxnHookAdd(http_ctx->txnp, TS_HTTP_POST_REMAP_HOOK, http_ctx->cinfo.contp);
      http_ctx->has_hook = 1;
      lua_pushvalue(L, 2);
      lua_setglobal(L, TS_LUA_FUNCTION_POST_REMAP);
    } else {
      lua_pushvalue(L, 2);
      lua_setglobal(L, TS_LUA_FUNCTION_G_POST_REMAP);
    }
    break;

  case TS_LUA_HOOK_OS_DNS:
    if (http_ctx) {
      TSHttpTxnHookAdd(http_ctx->txnp, TS_HTTP_OS_DNS_HOOK, http_ctx->cinfo.contp);
      http_ctx->has_hook = 1;
      lua_pushvalue(L, 2);
      lua_setglobal(L, TS_LUA_FUNCTION_OS_DNS);
    } else {
      lua_pushvalue(L, 2);
      lua_setglobal(L, TS_LUA_FUNCTION_G_OS_DNS);
    }
    break;

  case TS_LUA_HOOK_READ_CACHE_HDR:
    if (http_ctx) {
      TSHttpTxnHookAdd(http_ctx->txnp, TS_HTTP_READ_CACHE_HDR_HOOK, http_ctx->cinfo.contp);
      http_ctx->has_hook = 1;
      lua_pushvalue(L, 2);
      lua_setglobal(L, TS_LUA_FUNCTION_READ_CACHE);
    } else {
      lua_pushvalue(L, 2);
      lua_setglobal(L, TS_LUA_FUNCTION_G_READ_CACHE);
    }
    break;

  case TS_LUA_HOOK_TXN_CLOSE:
    if (http_ctx) {
      // we don't need to add a hook because we already have added one by default
      lua_pushvalue(L, 2);
      lua_setglobal(L, TS_LUA_FUNCTION_TXN_CLOSE);
    } else {
      lua_pushvalue(L, 2);
      lua_setglobal(L, TS_LUA_FUNCTION_G_TXN_CLOSE);
    }
    break;

  case TS_LUA_REQUEST_TRANSFORM:
  case TS_LUA_RESPONSE_TRANSFORM:
    if (http_ctx) {
      connp = TSTransformCreate(ts_lua_transform_entry, http_ctx->txnp);
      ts_lua_create_http_transform_ctx(http_ctx, connp);

      if (entry == TS_LUA_REQUEST_TRANSFORM) {
        TSHttpTxnHookAdd(http_ctx->txnp, TS_HTTP_REQUEST_TRANSFORM_HOOK, connp);
      } else {
        TSHttpTxnHookAdd(http_ctx->txnp, TS_HTTP_RESPONSE_TRANSFORM_HOOK, connp);
      }
    }
    break;

  default:
    break;
  }

  return 0;
}
