package ru.yandex.autotests.direct.scriptrunner.service.exportmaster;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import ru.yandex.autotests.direct.scriptrunner.service.scripts.BulkScriptRunner;
import ru.yandex.autotests.direct.scriptrunner.service.scripts.ScriptDBConfig;
import ru.yandex.autotests.direct.scriptrunner.service.scripts.ScriptRunResult;
import ru.yandex.autotests.direct.scriptrunner.service.scripts.ScriptRunTask;
import ru.yandex.autotests.direct.scriptrunner.service.scripts.ScriptrunnerServerException;
import ru.yandex.autotests.direct.scriptrunner.service.scripts.Scripts;
import ru.yandex.autotests.direct.scriptrunner.service.scripts.TaskVerifier;
import ru.yandex.autotests.direct.scriptrunner.service.utils.DbConfigUtils;

@Service
public class ExportMasterService {
    private final Logger log = LoggerFactory.getLogger(ExportMasterService.class);
    private Map<ScriptDBConfig, BulkScriptRunner> scriptRunnerMap = new HashMap<>();
    private Lock lock = new ReentrantLock();

    public ScriptRunResult runBsExportMaster(ScriptRunTask task) {
        try {
            TaskVerifier.checkTask(task);
            setDbHostIfEmpty(task);
            BulkScriptRunner runner = obtainScriptRunner(task.getScriptDBConfig());
            return runner.runScript(task.getScriptRunParams());
        } catch (Exception e) {
            Exception sse = new ScriptrunnerServerException("error while running bsExportMaster.pl", e);
            log.error("error while running bsExportMaster.pl: " + task.toString());
            return new ScriptRunResult(null, null, sse.toString());
        }
    }

    private void setDbHostIfEmpty(ScriptRunTask task) {
        ScriptDBConfig dbConfig = task.getScriptDBConfig();
        if (dbConfig.getDbHost() == null) {
            dbConfig.setDbHost(DbConfigUtils.getDbHost(task.getScriptRunParams().getHost()));
        }
    }

    private BulkScriptRunner obtainScriptRunner(ScriptDBConfig scriptDBConfig) {
        lock.lock();
        try {
            BulkScriptRunner runner = scriptRunnerMap.get(scriptDBConfig);
            if (runner == null) {
                runner = new BulkScriptRunner(Scripts.BS_EXPORT_MASTER);
                scriptRunnerMap.put(scriptDBConfig, runner);
            }
            return runner;
        } finally {
            lock.unlock();
        }
    }

}
