/*
 * Copyright 2008-2018 Aerospike, Inc.
 *
 * Portions may be licensed to Aerospike, Inc. under one or more contributor
 * license agreements.
 *
 * Licensed 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 <aerospike/mod_lua_geojson.h>
#include <aerospike/as_val.h>
#include <aerospike/mod_lua_val.h>
#include <aerospike/mod_lua_reg.h>
#include <citrusleaf/alloc.h>
#include <citrusleaf/cf_byte_order.h>
#include <stddef.h>

#include "internal.h"

/*******************************************************************************
 * MACROS
 ******************************************************************************/

#define OBJECT_NAME "geojson"
#define CLASS_NAME  "GeoJSON"

/*******************************************************************************
 * BOX FUNCTIONS
 ******************************************************************************/

as_geojson * mod_lua_togeojson(lua_State * l, int index) {
	mod_lua_box * box = mod_lua_tobox(l, index, CLASS_NAME);
	return (as_geojson *) mod_lua_box_value(box);
}

as_geojson * mod_lua_pushgeojson(lua_State * l, as_geojson * b) {
	mod_lua_box * box = mod_lua_pushbox(l, MOD_LUA_SCOPE_LUA, b, CLASS_NAME);
	return (as_geojson *) mod_lua_box_value(box);
}

#if 0
static as_geojson * mod_lua_checkgeojson(lua_State * l, int index) {
	mod_lua_box * box = mod_lua_checkbox(l, index, CLASS_NAME);
	return (as_geojson *) mod_lua_box_value(box);
}
#endif

static int mod_lua_geojson_gc(lua_State * l) {
	mod_lua_freebox(l, 1, CLASS_NAME);
	return 0;
}

/*******************************************************************************
 * FUNCTIONS
 ******************************************************************************/

static int mod_lua_geojson_new(lua_State * l)
{
	int argc = lua_gettop(l);
	if (argc != 2) {
		return 0;
	}

	const char * geostr = luaL_optstring(l, 2, NULL);
	if (geostr == NULL) {
		return 0;
	}

	as_geojson * geo = as_geojson_new(cf_strdup(geostr), true);
	if (geo == NULL) {
		return 0;
	}

	mod_lua_pushgeojson(l, geo);
	return 1;
}

static int mod_lua_geojson_tostring(lua_State * l)
{
	// we expect 1 arg
	if ( lua_gettop(l) != 1 ) {
		lua_pushinteger(l, 0);
		return 1;
	}

	mod_lua_box *   box = mod_lua_checkbox(l, 1, CLASS_NAME);
	as_val *        val = mod_lua_box_value(box);
	char *          str = NULL;

	if ( val ) {
		str = as_val_tostring(val);
	}

	if ( str ) {
		lua_pushstring(l, str);
		cf_free(str);
	}
	else {
		lua_pushstring(l, "GeoJSON()");
	}

	return 1;
}

/******************************************************************************
 * OBJECT TABLE
 *****************************************************************************/

static const luaL_Reg geojson_object_table[] = {
	{0, 0}
};

static const luaL_Reg geojson_object_metatable[] = {
	{"__call",          mod_lua_geojson_new},
	{0, 0}
};

/******************************************************************************
 * CLASS TABLE
 *****************************************************************************/

static const luaL_Reg geojson_class_metatable[] = {
	{"__tostring",      mod_lua_geojson_tostring},
	{"__gc",            mod_lua_geojson_gc},
	{0, 0}
};

/******************************************************************************
 * REGISTER
 *****************************************************************************/

int mod_lua_geojson_register(lua_State * l) {
	mod_lua_reg_object(l, OBJECT_NAME,
					   geojson_object_table, geojson_object_metatable);
	mod_lua_reg_class(l, CLASS_NAME, NULL, geojson_class_metatable);
	return 1;
}
