//database file location to read in the json?

//deployer SLmanager implementation
// Copyright (C) 2024 Jean-Cloud
// GNU General Public License v3

#include <iostream>
#include <cstring>
#include <vector>
#include <list>
#include <sqlite3.h>
#include <sstream>
#include "Service.h"
#include "SQLmanager.h"

using namespace std;

//private methods
int callback(void * data, int argc, char **argv, char **azColName) {
    int userID = stoi(argv[0]);  
    string serviceName = argv[1];
    string serveur=argv[2]; 
    string ip=argv[3];
    //extract the IPs as integers
    stringstream ss(ip);
    string nb;
    while (getline(ss,nb,',')){
      stoi(nb);
    }

     
    cout << userID << serviceName << serveur << ip << endl;
    //create a data structure to store servers
    return 0;
}

//constructor
SQLmanager::SQLmanager()
{
   sqlite3 *db;
   int rc;
   int res;
   char* errMess=0;
   const char * data="Callback function called";
   rc=sqlite3_open("general.db", &db);
   //CAREFUL: enable FK constraints? or not cause just reading?
   if(rc) {
      cerr << "Error. Database cannot be opened." << endl << sqlite3_errmsg(db) << endl;
   } else {
      cout << "Database opened" << endl;
      //change this to get the info to create both the service and the server
      string query="SELECT services.id,services.name,servers.name,GROUP_CONCAT(CASE WHEN IPs.value IS NOT NULL THEN IPs.value END) FROM services JOIN servers_services ON services.name = servers_services.name_service JOIN servers ON servers.name = servers_services.name_server CROSS JOIN json_each(servers.IPs) AS IPs GROUP BY services.id, services.name, servers.name;";
      res = sqlite3_exec(db, query.c_str(), callback, (void*)data, &errMess); 
      if( res != SQLITE_OK ) {
         cout << errMess << endl;
         sqlite3_free(errMess);
      } else {
         cout << "Data extracted from database." << endl;
      }
      
   }
   sqlite3_close(db);
}

//destructor inline

//public methods
vector<Service> SQLmanager::GetServices() const
{

}
const Service * SQLmanager::FindServiceByUsername(string aUsername) const
{

}
const Service * SQLmanager::FindServiceByID(int aUserID) const
{

}
//list<const Service*> FindServicesByServer(string aServer) const;
int SQLmanager::isServiceOnServer(string serviceUsername)
{

}





//int isServiceOnServer(string serviceUsername)
//this method tests if a certain service is on the current server
//it looks into the /etc/hosts file thanks to a pipe to a separate bash process
// {   
//     string cmd ="getent hosts " +serviceUsername;  
//     string result = BashManager::ExecuteAndReadResult(cmd);
//     if(result.find("::1")!=string::npos){ //if result contains "::1" which is the notation for loopback in IpV6
//         cout << "service " << serviceUsername << " on server" << endl;
//         return 0;
//     }
//     cout << "service" << serviceUsername << " not on server" << endl;
//     return 1;
//    return 0;
// }