/*******************************************************************************
 * Copyright 2022 Aerospike, Inc.
 *
 * 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 <Python.h>

#include <aerospike/aerospike_info.h>
#include <aerospike/as_error.h>
#include <aerospike/as_node.h>
#include <aerospike/as_cluster.h>

#include "client.h"
#include "conversions.h"
#include "exceptions.h"
#include "policy.h"

/**
 *******************************************************************************************************
 * Return the base64 representation of the passed in CDT ctx.
 *
 * @param self                  AerospikeClient object
 * @param args                  The args is a tuple object containing an argument
 *                              list passed from Python to a C function
 * @param kwds                  Dictionary of keywords
 *
 * Returns a string containing the base64 representation of the passed in CDT ctx.
 * In case of error, appropriate exceptions will be raised.
 *******************************************************************************************************
 */
PyObject *AerospikeClient_GetCDTCTXBase64(AerospikeClient *self,
											  PyObject *args, PyObject *kwds)
{
	// function args
	PyObject *py_cdtctx = NULL;
	as_cdt_ctx ctx;
	bool ctx_in_use = false;

	char *base64 = NULL;
	PyObject *py_response = NULL;

	as_error err;
	as_error_init(&err);

	static char *kwlist[] = {"ctx", NULL};
	if (PyArg_ParseTupleAndKeywords(args, kwds, "O:get_cdtctx_base64",
									kwlist, &py_cdtctx) == false) {
		return NULL;
	}

	if (py_cdtctx == NULL || !PyDict_Check(py_cdtctx)) {
		as_error_update(&err, AEROSPIKE_ERR_PARAM,
						"parameter is not dict type");
		goto CLEANUP;
	}

	PyObject *py_ctx = PyDict_GetItemString(py_cdtctx, CTX_KEY);
	if (py_ctx == NULL) {
		as_error_update(&err, AEROSPIKE_ERR_PARAM,
						"param dict does not contain ctx key");
		goto CLEANUP;
	}
 	if (!PyList_Check(py_ctx) || !PyList_Size(py_ctx)){
		as_error_update(&err, AEROSPIKE_ERR_PARAM,
						"cdt ctx list entries are empty");
		goto CLEANUP;
	}

	as_static_pool static_pool;
	memset(&static_pool, 0, sizeof(static_pool));

	if (get_cdt_ctx(self, &err, &ctx, py_cdtctx, &ctx_in_use, &static_pool,
					SERIALIZER_PYTHON) != AEROSPIKE_OK) {
		goto CLEANUP;
	}
	if(!ctx_in_use) {
		as_error_update(&err, AEROSPIKE_ERR_PARAM,
						"cdt ctx must be valid "
						", generated by aerospike cdt context helper");
	}

	//convert cdtctx to base64
	uint32_t capacity = as_cdt_ctx_base64_capacity(&ctx);
	base64 = cf_malloc(capacity);
	bool rv = as_cdt_ctx_to_base64(&ctx, base64, capacity);
	if(!rv) {
		as_error_update(&err, AEROSPIKE_ERR_PARAM,
						"failed to convert cdt ctx to base64 ");
		goto CLEANUP;
	}

	py_response = PyUnicode_FromString((const char *)base64);

CLEANUP:

	if (base64 != NULL) {
		cf_free(base64);
	}

	if (err.code != AEROSPIKE_OK) {
		PyObject *py_err = NULL;
		error_to_pyobject(&err, &py_err);
		PyObject *exception_type = raise_exception(&err);
		PyErr_SetObject(exception_type, py_err);
		Py_DECREF(py_err);
		return NULL;
	}

	return py_response;
}