/**
* Nudsf_DataRepository
* Nudsf Data Repository Service. © 2021, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved. 
*
* The version of the OpenAPI document: 1.1.0-alpha.2
* 
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/

#include "RecordCRUDApiImpl.h"
#include "logger.hpp"
#include <list>
namespace org {
namespace openapitools {
namespace server {
namespace api {

using namespace org::openapitools::server::model;

RecordCRUDApiImpl::RecordCRUDApiImpl(std::shared_ptr<Pistache::Rest::Router> rtr,MYSQL *mysql)
    : RecordCRUDApi(rtr)
    { 
        mysql_record = mysql;
    }

void RecordCRUDApiImpl::create_or_modify_record(const std::string &realmId, const std::string &storageId, const std::string &recordId, const Record &record, const Pistache::Optional<Pistache::Http::Header::Raw> &ifNoneMatch, const Pistache::Optional<Pistache::Http::Header::Raw> &ifMatch, const Pistache::Optional<bool> &getPrevious, const Pistache::Optional<std::string> &supportedFeatures, Pistache::Http::ResponseWriter &response) {
    const std::string change_dabatase = "use " + realmId  ;
	Logger::udsf_server().info("------------%s------------------",change_dabatase.c_str());
    if(mysql_query(mysql_record, change_dabatase.c_str())){
        Logger::udsf_server().error("mysql_real_query failure！SQL(%s) error:%s\n",change_dabatase.c_str(), mysql_error(mysql_record));
        return;
    }
    std::map<std::string, std::set<std::string>> meta_map = record.getMeta().getTags();
    std::map<std::string, std::set<std::string>>::iterator it_meta;   
    int i_meta=0;
    std::string meta[meta_map.size()];
    for(it_meta=meta_map.begin();it_meta!=meta_map.end();)
    {
        meta[i_meta] = it_meta->first;
        meta_map.erase(it_meta++); 
        i_meta++;
    }
    std::map<std::string, std::string> blocks_map = record.getBlocks().at(0);
    std::string block[blocks_map.size()];
    std::map<std::string, std::string>::iterator it_block;  
    int i_block=0;
    for(it_block=blocks_map.begin();it_block!=blocks_map.end();)
    {  
        block[i_block] = it_block->first;
        blocks_map.erase(it_block++); 
        i_block++;
    }
    std::string extrnal = "create table IF NOT EXISTS "+ storageId + "(";
    for(int i=0;i<i_meta;i++)
    {
        extrnal = extrnal + meta[i] + " varchar(32)";     
        extrnal = extrnal  + std::string(",") ;
    }
    for(int j=0;j<i_block;j++)
    {
        extrnal = extrnal + block[j] + " varchar(32)"; 
        if(j==(i_block-1)){
            break;
        }        
        extrnal = extrnal  + std::string(",") ;
    }
    const std::string create_table = extrnal + ")"; 
    Logger::udsf_server().info("%s", create_table.c_str());
    if(mysql_query(mysql_record, create_table.c_str())){
        Logger::udsf_server().error("mysql_real_query failure！SQL(%s) error:%s\n", create_table.c_str(),mysql_error(mysql_record));
        return;
    }

    extrnal = "insert into  "+ storageId + " values(\'";
    for(int ii=0;ii<i_meta;ii++)
    {
        extrnal = extrnal +(*(record.getMeta().getTags().find(meta[ii])->second.begin())).c_str()  + "\', \'";     
    }
    for(int jj=0;jj<i_block;jj++)
    {
        extrnal = extrnal + record.getBlocks().at(0).find(block[jj])->second.c_str()  +"\'";     
        if(jj==(i_block-1)){
            break;
        }    
        extrnal = extrnal +  ", \'"  ;    
    }
    const std::string insert_record = extrnal + ")";
    Logger::udsf_server().info("%s", insert_record.c_str());
    if(mysql_query(mysql_record, insert_record.c_str())){
        Logger::udsf_server().error("mysql_real_query failure！SQL(%s) error:%s\n", insert_record.c_str(),mysql_error(mysql_record));
        return;
    }
    response.send(Pistache::Http::Code::Created);
}
void RecordCRUDApiImpl::delete_record(const std::string &realmId, const std::string &storageId, const std::string &recordId, const Pistache::Optional<Pistache::Http::Header::Raw> &ifMatch, const Pistache::Optional<bool> &getPrevious, const Pistache::Optional<std::string> &supportedFeatures, Pistache::Http::ResponseWriter &response) {
    response.send(Pistache::Http::Code::Ok, "Do some magic RecordCRUDApiImpl::delete_record\n");
}
void RecordCRUDApiImpl::get_meta(const std::string &realmId, const std::string &storageId, const std::string &recordId, const Pistache::Optional<Pistache::Http::Header::Raw> &ifNoneMatch, const Pistache::Optional<Pistache::Http::Header::Raw> &ifModifiedSince, const Pistache::Optional<std::string> &supportedFeatures, Pistache::Http::ResponseWriter &response) {
    response.send(Pistache::Http::Code::Ok, "Do some magic RecordCRUDApiImpl::get_meta\n");
}
void RecordCRUDApiImpl::get_record(const std::string &realmId, const std::string &storageId, const std::string &recordId, const Pistache::Optional<Pistache::Http::Header::Raw> &ifNoneMatch, const Pistache::Optional<Pistache::Http::Header::Raw> &ifModifiedSince, const Pistache::Optional<std::string> &supportedFeatures, Pistache::Http::ResponseWriter &response) {
    const std::string change_dabatase = "use " + realmId  ;
	printf("------------%s------------------\n",change_dabatase.c_str());
    if(mysql_query(mysql_record, change_dabatase.c_str())){
        Logger::udsf_server().error("mysql_real_query failure！SQL(%s) error:%s\n",change_dabatase.c_str(), mysql_error(mysql_record));
        return;
    }

    const std::string chose_record = "select * from  "+  storageId + " where RECORD_ID="+recordId ;
    if(mysql_query(mysql_record, chose_record.c_str())){
        Logger::udsf_server().error("mysql_real_query failure！SQL(%s) error:%s\n", chose_record.c_str(),mysql_error(mysql_record));
        return;
    }

    MYSQL_RES *result = mysql_store_result(mysql_record);
    if (NULL == result)
	{
		printf("mysql_store_result failure！SQL(%s) error(%d):%s\n", chose_record,mysql_errno(mysql_record), mysql_error(mysql_record));
		return;
	}

    int num_rows = mysql_num_rows(result);//2
	printf("got:%d row:\n", (int)num_rows);
    int num_fields = mysql_num_fields(result);//3
	printf("number of fields:%d\n", (int)num_fields);
    
    MYSQL_FIELD *field = nullptr;
    nlohmann::json json;
    MYSQL_ROW row;
    while (row = mysql_fetch_row(result))
		{
			unsigned long *lengths = mysql_fetch_lengths(result);
			for (int i = 0; i < num_fields; i++)
			{
				char *filed = row[i];
				unsigned int field_length = lengths[i];
                field = mysql_fetch_field(result);
                json[field->name] = filed;
				printf("column[%d],length[%d],field[%s]:data[%s]\n", i, field_length, field->name,filed ? filed : "null");
			}
			printf("\n");
		}
	mysql_free_result(result);

    response.send(Pistache::Http::Code::Ok, json.dump());
}
void RecordCRUDApiImpl::search_record(const std::string &realmId, const std::string &storageId, const Pistache::Optional<int32_t> &limitRange, const Pistache::Optional<SearchExpression> &filter, const Pistache::Optional<bool> &countIndicator, const Pistache::Optional<std::string> &supportedFeatures, Pistache::Http::ResponseWriter &response) {
    response.send(Pistache::Http::Code::Ok, "Do some magic RecordCRUDApiImpl::search_record\n");
}
void RecordCRUDApiImpl::update_meta(const std::string &realmId, const std::string &storageId, const std::string &recordId, const std::vector<PatchItem> &patchItem, const Pistache::Optional<Pistache::Http::Header::Raw> &ifMatch, const Pistache::Optional<std::string> &supportedFeatures, Pistache::Http::ResponseWriter &response) {
    response.send(Pistache::Http::Code::Ok, "Do some magic RecordCRUDApiImpl::update_meta\n");
}

}
}
}
}

