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

#include <filesystem>
#include "DockerModule.h"
#include "BashManager.h"

//constructor and destructor inline 
DockerModule::DockerModule()
{
	name="Docker";
}

//private methods

int DockerModule::removeContainersCreatedByDockerCompose()
{
	return BashManager::Execute("docker-compose down --rmi all --remove-orphans");
}

int DockerModule::removeContainersWithServiceName(string serviceName)
{	
	//constructing the name of the docker container from the name of the service by replacing . with _
	size_t pos=serviceName.find('.');
	if (pos==string::npos){
		cerr << "Error. Service name should contain a ." << endl;
		return -1;
	}else {
		string dockerService=serviceName;
		dockerService=dockerService.substr(0,pos)+dockerService.substr(pos+1);
		//removing containers with the name of the service
		string cmd="while read container ; do \
    	[ -z \"$container\" ] && continue || true ; \
    	docker rm \"$container\" ; \
		done <<< \"$(docker ps | grep '" + dockerService + "' | cut -d ' ' -f 1)\"";
		return BashManager::Execute(cmd);	
	}
}
//public methods
int DockerModule::Prepare()
{
	return BashManager::Execute("systemctl start docker docker.socket");
}

int DockerModule::Deploy (string serviceUsername)
{
	cout << "docker module deploy" << endl;
	//test if there is a docker-compose.yml or docker-compose.yaml
	string docker_compose="./services/"+serviceUsername+"/docker-compose.yml";
	if(!(filesystem::exists(docker_compose))){
		docker_compose="./services/"+serviceUsername+"/docker-compose.yaml";
		if(!(filesystem::exists(docker_compose))){
			cout << "No docker-compose for this service." << endl;
			return 0;
		}
	}
	//pulling images
	int pulling =BashManager::Execute("docker-compose pull")==0;
	if(pulling==0){
		//starting service
		int starting=BashManager::Execute("docker-compose up -d --remove-orphans"); 
	}else{
		cerr << "Error in "<< name << "deploying "<< serviceUsername << endl;
		return -1;
	}
	return 0;
		
}

int DockerModule::Remove (string serviceUsername)
{
	//remove unwanted containers
	removeContainersCreatedByDockerCompose();	
	removeContainersWithServiceName(serviceUsername);
	return 0;
}

int DockerModule::Clean()
{
	return 0;
} 
