/**
* @file:    $RCSfile: base64.cpp,v $
* @brief:   base64 include
*
* @version: $Revision: 1.00 $
* @date:    $Date: 2024/09/24 18:34:00 $
* @author:  $Author: caizhouyu $
* @state:   $State: Exp $
*
* @latest:  $Id: base64.cpp,v 1.00 2023/10/24 18:34:00 caizhouyu Exp $
*
*/

using namespace std;

#include <stdio.h>

#include <stdlib.h>
#include <string>

#include "../mms/db_interface.h"
#include "../json/cjson.h"//WW 2023-08-27新增json解析函数
#include "../include/curl/curl.h" 

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */


	// Base64 编码表  
	const char base64_chars[] =
		"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
		"abcdefghijklmnopqrstuvwxyz"
		"0123456789+/";

	//base64 解码表
	static const unsigned char base64_decode_table[] = {
		//每行16个
		0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,                //1 - 16
		0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,                //17 - 32
		0,0,0,0,0,0,0,0,0,0,0,62,0,0,0,63,              //33 - 48
		52,53,54,55,56,57,58,59,60,61,0,0,0,0,0,0,      //49 - 64
		0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,           //65 - 80
		15,16,17,18,19,20,21,22,23,24,25,0,0,0,0,0,     //81 - 96
		0,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, //97 - 112
		41,42,43,44,45,46,47,48,49,50,51,0,0,0,0,0      //113 - 128
	};

	/**
	* @brief base64_decode     base64解码
	* @param indata            需解码的数据
	* @param inlen             需解码的数据大小
	* @param outdata           解码后输出的数据
	* @param outlen            解码后输出的数据大小
	* @return  int             0：成功    -1：无效参数
	* 注意：解码的数据的大小必须大于4，且是4的倍数
	*/
	int base64_decode(const char* indata, int inlen, char* outdata, long* outlen)
	{
		if (indata == NULL || inlen <= 0 || (outdata == NULL && outlen == NULL)) {
			return -1;
		}
		if (inlen < 4 || inlen % 4 != 0) { //需要解码的数据长度不是4的倍数  //inlen < 4 ||
			return -1;
		}

		int i, j;

		//计算解码后的字符串长度
		int len = inlen / 4 * 3;
		if (indata[inlen - 1] == '=') {
			len--;
		}
		if (indata[inlen - 2] == '=') {
			len--;
		}

		if (outdata != NULL) {
			for (i = 0, j = 0; i < inlen; i += 4, j += 3) {
				outdata[j] = (base64_decode_table[(unsigned char)indata[i]] << 2) | (base64_decode_table[(unsigned char)indata[i + 1]] >> 4);
				outdata[j + 1] = (base64_decode_table[(unsigned char)indata[i + 1]] << 4) | (base64_decode_table[(unsigned char)indata[i + 2]] >> 2);
				outdata[j + 2] = (base64_decode_table[(unsigned char)indata[i + 2]] << 6) | (base64_decode_table[(unsigned char)indata[i + 3]]);
			}
		}
		if (outlen != NULL) {
			*outlen = len;
		}
		return 0;
	}

	// Base64 编码函数  
	char* base64_encode_char(const unsigned char* data, size_t input_length, size_t* output_length) {
		*output_length = 4 * ((input_length + 2) / 3); // 输出长度计算  
		char* encoded_data = (char*)malloc(*output_length + 1); // 分配内存，+1 为 '\0'  
		if (encoded_data == NULL) return NULL;

		for (int i = 0, j = 0; i < input_length;) {
			uint32_t octet_a = i < input_length ? data[i++] : 0;
			uint32_t octet_b = i < input_length ? data[i++] : 0;
			uint32_t octet_c = i < input_length ? data[i++] : 0;

			uint32_t triple = (octet_a << 16) | (octet_b << 8) | octet_c;

			encoded_data[j++] = base64_chars[(triple >> 18) & 0x3F];
			encoded_data[j++] = base64_chars[(triple >> 12) & 0x3F];
			encoded_data[j++] = (i * 2 / 3) < *output_length ? base64_chars[(triple >> 6) & 0x3F] : '=';
			encoded_data[j++] = (i * 2 + 1 / 3) < *output_length ? base64_chars[triple & 0x3F] : '=';
		}

		encoded_data[*output_length] = '\0'; // 添加字符串结束符  
		return encoded_data;
	}

	/// <summary>
	/// 判断字符串是否为power{}格式
	/// </summary>
	/// <param name="str">待提取字符串</param>
	/// <param name="output">结果字段</param>
	/// <param name="output_size">字段长度限制</param>
	/// <param name="extracted_length">提取出的内容长度</param>
	/// <returns></returns>
	bool extract_if_power(const char* str, char* output, size_t output_size, size_t* extracted_length) {
		const char* prefix = "power{";
		size_t prefix_length = strlen(prefix);

		// 检查前缀  
		if (strncmp(str, prefix, prefix_length) != 0) {
			return false; // 前缀不匹配  
		}

		// 查找闭合的花括号  
		const char* close_brace = strchr(str + prefix_length, '}');
		if (close_brace == NULL) {
			return false; // 没有找到闭合的花括号  
		}

		// 计算要提取的内容长度  
		size_t content_length = close_brace - (str + prefix_length);
		if (content_length >= output_size) {
			return false; // 内容太长，无法放入输出缓冲区  
		}

		// 复制内容到输出缓冲区  
		strncpy(output, str + prefix_length, content_length);
		output[content_length] = '\0'; // 添加空终止符  
		printf("text: %s,length:%d\n", output, content_length); // 注意：这里需要确保文本是以null终止的字符串  
		// 设置提取出的内容长度  
		*extracted_length = content_length;

		return true; // 提取成功  
	}

#ifdef __cplusplus
}
#endif
