/*
  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_util.h"

static TSTextLogObject ts_log;

static int ts_lua_log_object_creat(lua_State *L);
static int ts_lua_log_object_write(lua_State *L);
static int ts_lua_log_object_destroy(lua_State *L);

static void ts_lua_inject_log_object_creat_api(lua_State *L);
static void ts_lua_inject_log_object_write_api(lua_State *L);
static void ts_lua_inject_log_object_destroy_api(lua_State *L);

void
ts_lua_inject_log_api(lua_State *L)
{
  lua_newtable(L);

  ts_lua_inject_log_object_creat_api(L);
  ts_lua_inject_log_object_write_api(L);
  ts_lua_inject_log_object_destroy_api(L);

  lua_setfield(L, -2, "log");
}

static void
ts_lua_inject_log_object_creat_api(lua_State *L)
{
  lua_pushcfunction(L, ts_lua_log_object_creat);
  lua_setfield(L, -2, "object_creat");
}

static int
ts_lua_log_object_creat(lua_State *L)
{
  const char  *log_name;
  size_t       name_len;
  int          log_mode;
  TSReturnCode error;

  log_name = luaL_checklstring(L, -2, &name_len);

  if (lua_isnil(L, 3)) {
    TSError("[ts_lua][%s] No log name!!", __FUNCTION__);
    return -1;
  } else {
    log_mode = luaL_checknumber(L, 3);
  }

  error = TSTextLogObjectCreate(log_name, log_mode, &ts_log);

  if (!ts_log || error == TS_ERROR) {
    TSError("[ts_lua][%s] Unable to create log <%s>", __FUNCTION__, log_name);
    return -1;
  }
  return 0;
}

static void
ts_lua_inject_log_object_write_api(lua_State *L)
{
  lua_pushcfunction(L, ts_lua_log_object_write);
  lua_setfield(L, -2, "object_write");
}

static int
ts_lua_log_object_write(lua_State *L)
{
  const char *text;
  size_t      text_len;

  text = luaL_checklstring(L, 1, &text_len);
  if (ts_log) {
    TSTextLogObjectWrite(ts_log, (char *)text, nullptr);
  } else {
    TSError("[ts_lua][%s] log object does not exist for write", __FUNCTION__);
  }

  return 0;
}

static void
ts_lua_inject_log_object_destroy_api(lua_State *L)
{
  lua_pushcfunction(L, ts_lua_log_object_destroy);
  lua_setfield(L, -2, "object_destroy");
}

static int
ts_lua_log_object_destroy(lua_State *L ATS_UNUSED)
{
  if (TSTextLogObjectDestroy(ts_log) != TS_SUCCESS) {
    TSError("[ts_lua][%s] TSTextLogObjectDestroy error!", __FUNCTION__);
  }

  return 0;
}
