/**
* 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>
#include <string>
#include <ctime>
//#include "pch.h"
#include "Connection.h"
#include "ConnectionPool.h"
namespace org {
namespace openapitools {
namespace server {
namespace api {

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

RecordCRUDApiImpl::RecordCRUDApiImpl(std::shared_ptr<Pistache::Rest::Router> rtr)
    : 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) {

    ConnectionPool* p = ConnectionPool::getConnectionPool();
    shared_ptr<Connection> conn = p->getConnetcion();
    const std::string change_dabatase = "use " + realmId  ;
    printf("------------%s------------------\n",change_dabatase.c_str());
    if( !conn->update(change_dabatase)){
        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::set<nlohmann::json> block_set = record.getBlocks();
    std::string block_name[block_set.size()];
    std::string block_type[block_set.size()];
    std::string block_vlaue[block_set.size()];
    std::set<nlohmann::json>::iterator it_block;  
    int i_block=0;
    for(it_block=block_set.begin();it_block!=block_set.end();)
    {  
        
        block_name[i_block] = it_block->at("Content-ID");
        block_type[i_block] = it_block->at("Content-Type");
        if(block_type[i_block] == "JSON")
        {block_vlaue[i_block] = it_block->at("content").dump();}
        else{block_vlaue[i_block] = it_block->at("content");}
        block_set.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(64)";    
        extrnal = extrnal  + std::string(",") ;
    }
    for(int j=0;j<i_block;j++)
    {
        //extrnal = extrnal + block[j] + " varchar(32)"; 
        extrnal = extrnal + block_name[j] + " " + block_type[j]; 
        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( !conn->update(create_table)){
        return;
    }
        // //先查一下是否有这个recordid
    // //如果有recordid   变为修改，如果没有recordid再增加
    const std::string chose_record = "select * from  "+  storageId + " where  "+ recordId ;
    MYSQL_RES *result = conn->query(chose_record);
    if (NULL == result)
	{
		printf("mysql_store_result failure！SQL(%s) \n", chose_record.c_str());
		return;
	}
    if(mysql_num_rows(result) > 0)
    {
        //xiugai
        extrnal = "UPDATE " + storageId + " SET " ;
        for(int ui=0;ui<i_meta;ui++)
        {
            extrnal = extrnal + meta[ui] + "=" +  "\'" + (*(record.getMeta().getTags().find(meta[ui])->second.begin())).c_str() +  "\'";    
            extrnal = extrnal  + std::string(",") ;
        }
        for(int uj=0;uj<i_block;uj++)
        {
            //extrnal = extrnal + block[j] + " varchar(32)"; 
            extrnal = extrnal + block_name[uj] + "=" +  "\'" +block_vlaue[uj] + "\'"; 
            if(uj==(i_block-1)){
                break;
            }        
            extrnal = extrnal +  ", "  ;
        }
        const std::string update = extrnal + " where "  + recordId  ;
        Logger::udsf_server().info("%s", update.c_str());
        if( !conn->update(update)){
             return;
        }
        response.send(Pistache::Http::Code::Ok);
    }
    else
    {
        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 + block_vlaue[jj]  +"\'";     
            if(jj==(i_block-1)){
                break;
            }    
            extrnal = extrnal +  ", \'"  ;    
        }
        const std::string insert_record = extrnal + ")";
        Logger::udsf_server().info("%s", insert_record.c_str());
        if( !conn->update(insert_record)){
             return;
        }
        response.send(Pistache::Http::Code::Created);
    }
}
//     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::set<nlohmann::json> block_set = record.getBlocks();
//     std::string block_name[block_set.size()];
//     std::string block_type[block_set.size()];
//     std::string block_vlaue[block_set.size()];
//     std::set<nlohmann::json>::iterator it_block;  
//     int i_block=0;
//     for(it_block=block_set.begin();it_block!=block_set.end();)
//     {  
        
//         block_name[i_block] = it_block->at("Content-ID");
//         block_type[i_block] = it_block->at("Content-Type");
//         if(block_type[i_block] == "JSON")
//         {block_vlaue[i_block] = it_block->at("content").dump();}
//         else{block_vlaue[i_block] = it_block->at("content");}
//         block_set.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(64)";    
//         extrnal = extrnal  + std::string(",") ;
//     }
//     for(int j=0;j<i_block;j++)
//     {
//         //extrnal = extrnal + block[j] + " varchar(32)"; 
//         extrnal = extrnal + block_name[j] + " " + block_type[j]; 
//         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;
//     }
//     // //先查一下是否有这个recordid
//     // //如果有recordid   变为修改，如果没有recordid再增加
//     const std::string chose_record = "select * from  "+  storageId + " where  "+ 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));
//          mysql_free_result(result); 
// 		return;
// 	}
//     if(mysql_num_rows(result) > 0)
//     {
//         //xiugai
//         extrnal = "UPDATE " + storageId + " SET " ;
//         for(int ui=0;ui<i_meta;ui++)
//         {
//             extrnal = extrnal + meta[ui] + "=" +  "\'" + (*(record.getMeta().getTags().find(meta[ui])->second.begin())).c_str() +  "\'";    
//             extrnal = extrnal  + std::string(",") ;
//         }
//         for(int uj=0;uj<i_block;uj++)
//         {
//             //extrnal = extrnal + block[j] + " varchar(32)"; 
//             extrnal = extrnal + block_name[uj] + "=" +  "\'" +block_vlaue[uj] + "\'"; 
//             if(uj==(i_block-1)){
//                 break;
//             }        
//             extrnal = extrnal +  ", "  ;
//         }
//         const std::string update = extrnal + " where "  + recordId  ;
//         Logger::udsf_server().info("%s", update.c_str());
//         if(mysql_query(mysql_record, update.c_str())){
//              Logger::udsf_server().error("mysql_real_query failure！SQL(%s) error:%s\n", storageId.c_str(),mysql_error(mysql_record));
//             mysql_free_result(result); 
//              return;
//         }
//         mysql_free_result(result); 
//         response.send(Pistache::Http::Code::Ok);
//     }
//     else
//     {
//         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 + block_vlaue[jj]  +"\'";     
//             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));
//              mysql_free_result(result); 
//             return;
//         }
//         mysql_free_result(result); 
// // do
// // {
// //   printf("total affected rows: %lld", mysql_affected_rows(mysql_record));
// //   if (!(result2= mysql_store_result(mysql_record)))
// //   {
// //      printf(stderr, "Got fatal error processing query/n");
// //      exit(1);
// //   }
// //   process_result_set(result2); /* client function */
// //   mysql_free_result(result2);
// // } while (!mysql_next_result(mysql_record));


//         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) {
    
    
    
    ConnectionPool* p = ConnectionPool::getConnectionPool();
    shared_ptr<Connection> conn = p->getConnetcion();
   
    const std::string change_dabatase = "use " + realmId  ;
    printf("------------%s------------------\n",change_dabatase.c_str());
    if( !conn->update(change_dabatase)){
        return;
    }
    const std::string chose_record = "select * from  "+  storageId + " where  "+ recordId  ;
    MYSQL_RES *result = conn->query(chose_record);
    if (NULL == result)
	{
		printf("mysql_store_result failure！SQL(%s) \n", chose_record.c_str());
		return;
	}

    int num_rows = mysql_num_rows(result);//2
	printf("got:%d row:\n", (int)num_rows);
    if(num_rows == 0 ){
        nlohmann::json json;
        response.send(Pistache::Http::Code::Ok, json.dump());
    }
    else{
        int num_fields = mysql_num_fields(result);//3
        printf("number of fields:%d\n", (int)num_fields);
        
        MYSQL_FIELD *field = nullptr;
        nlohmann::json json;
        //nlohmann::json sum;
        MYSQL_ROW row;

        int num_meta;
        num_meta =2 ;
        nlohmann::json objects; 
        std::string Blocks_objects;
        std::string Meta_objects;
        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);
                   // mysql_fetch_fields(result);
                  
                    //json[field->name] = filed;
                    
                    printf("column[%d],length[%d],field[%s]:data[%s]\n", i, field_length, field->name,filed ? filed : "null");
                    if(i<num_meta)
                    {
                        json[field->name] = nlohmann::json::array({filed});
                        objects["meta"]["tags"].update(json);
                        //Meta_objects = Meta_objects + json.dump();
                        //if(i != num_meta-1){ Meta_objects = Meta_objects + ",";}
                        json = {};
                    }
                    else{
                        json["Content-ID"] = field->name ;
                        printf("field->type---%d\n",(int)field->type);
                        switch (field->type)
                        {
                            case 253:
                            {
                                printf("253\n");
                                json["Content-Type"] = "varchar";
                                break;
                            }
                            case 245:
                            {
                                printf("245\n");
                                json["Content-Type"] = "JSON";
                                break;
                            }
                        }
                        if(json["Content-Type"] == "JSON")
                        {
                            json["content"] = nlohmann::json::parse(filed) ;
                        }
                        else
                        {
                            json["content"] = filed ;
                        }
                        //Blocks_objects = Blocks_objects + json.dump() ;
                        objects["blocks"].push_back(json);
                        //if(i != num_fields-1){ Blocks_objects = Blocks_objects + ",";}
                        json = {};
                    }
                    //if(i != num_fields-1){ objects = objects + ",";}
                }
                printf("\n");
            }
        mysql_free_result(result);
        // MYSQL_RES * pRes;
        // int nError = mysql_query(m_pConn, strSQL);
        // do 
        // {
        //     pRes = mysql_use_result(m_pConn);
        //     mysql_free_result(pRes);
        // } while (!mysql_next_result(m_pConn));
        printf("----------------------objects----------------%s\n", objects.dump().c_str());
        response.send(Pistache::Http::Code::Ok, objects.dump());   


    //const std::string change_dabatase = "use " + realmId  ;
	
    // 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  "+ 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);
    // if(num_rows == 0 ){
    //     nlohmann::json json;
    //     response.send(Pistache::Http::Code::Ok, json.dump());
    // }
    // else{
    //     int num_fields = mysql_num_fields(result);//3
    //     printf("number of fields:%d\n", (int)num_fields);
        
    //     MYSQL_FIELD *field = nullptr;
    //     nlohmann::json json;
    //     //nlohmann::json sum;
    //     MYSQL_ROW row;

    //     int num_meta;
    //     num_meta =2 ;
    //     nlohmann::json objects; 
    //     std::string Blocks_objects;
    //     std::string Meta_objects;
    //     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);
    //                // mysql_fetch_fields(result);
                  
    //                 //json[field->name] = filed;
                    
    //                 printf("column[%d],length[%d],field[%s]:data[%s]\n", i, field_length, field->name,filed ? filed : "null");
    //                 if(i<num_meta)
    //                 {
    //                     json[field->name] = nlohmann::json::array({filed});
    //                     objects["meta"]["tags"].update(json);
    //                     //Meta_objects = Meta_objects + json.dump();
    //                     //if(i != num_meta-1){ Meta_objects = Meta_objects + ",";}
    //                     json = {};
    //                 }
    //                 else{
    //                     json["Content-ID"] = field->name ;
    //                     printf("field->type---%d\n",(int)field->type);
    //                     switch (field->type)
    //                     {
    //                         case 253:
    //                         {
    //                             printf("253\n");
    //                             json["Content-Type"] = "varchar";
    //                             break;
    //                         }
    //                         case 245:
    //                         {
    //                             printf("245\n");
    //                             json["Content-Type"] = "JSON";
    //                             break;
    //                         }
    //                     }
    //                     if(json["Content-Type"] == "JSON")
    //                     {
    //                         json["content"] = nlohmann::json::parse(filed) ;
    //                     }
    //                     else
    //                     {
    //                         json["content"] = filed ;
    //                     }
    //                     //Blocks_objects = Blocks_objects + json.dump() ;
    //                     objects["blocks"].push_back(json);
    //                     //if(i != num_fields-1){ Blocks_objects = Blocks_objects + ",";}
    //                     json = {};
    //                 }
    //                 //if(i != num_fields-1){ objects = objects + ",";}
    //             }
    //             printf("\n");
    //         }
    //     mysql_free_result(result);
    //     // MYSQL_RES * pRes;
    //     // int nError = mysql_query(m_pConn, strSQL);
    //     // do 
    //     // {
    //     //     pRes = mysql_use_result(m_pConn);
    //     //     mysql_free_result(pRes);
    //     // } while (!mysql_next_result(m_pConn));
    //     printf("----------------------objects----------------%s\n", objects.dump().c_str());
    //     response.send(Pistache::Http::Code::Ok, objects.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");
}

}
}
}
}

