package org.bench4q.master.domain.service;

import java.util.List;
import java.util.UUID;

import org.apache.log4j.Logger;
import org.bench4q.master.domain.entity.Monitor;
import org.bench4q.master.domain.entity.MonitorResult;
import org.bench4q.master.domain.entity.TestPlan;
import org.bench4q.master.domain.entity.TestPlanScript;
import org.bench4q.master.domain.entity.TestPlanScriptResult;
import org.bench4q.master.domain.repository.TestPlanRepository;
import org.bench4q.master.exception.ExceptionLog;
import org.bench4q.master.helper.SessionHelper;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class TestResultSave {
	private SessionHelper sessionHelper;
	private TestPlanRepository testPlanRepository;
	private Logger logger = Logger.getLogger(TestResultSave.class);

	public TestResultSave() {
	}

	private TestPlanRepository getTestPlanRepository() {
		return testPlanRepository;
	}

	@Autowired
	private void setTestPlanRepository(TestPlanRepository testPlanRepository) {
		this.testPlanRepository = testPlanRepository;
	}

	private SessionHelper getSessionHelper() {
		return sessionHelper;
	}

	@Autowired
	private void setSessionHelper(SessionHelper sessionHelper) {
		this.sessionHelper = sessionHelper;
	}

	public void update(TestPlan testPlan, List<Object> messages) {
		Session session = this.getSessionHelper().openSession();
		try {
			TestPlan testPlanFromRepo = this.getTestPlanRepository()
					.doGetTestPlanBy(session,
							UUID.fromString(testPlan.getTestPlanRunId()));
			updateTestPlanResult(messages, testPlanFromRepo);
			saveUpdatedResult(testPlanFromRepo, session);
		} catch (Exception e) {
			Logger.getLogger(this.getClass()).info(e, e);
		} finally {
			if (session != null) {
				session.close();
			}
		}
	}

	private void updateTestPlanResult(List<Object> messages,
			TestPlan testPlanFromRepo) {
		for (Object message : messages) {
			if (message == null)
				return;
			if (message instanceof MonitorResult) {

				updateTestplanMonitorResult((MonitorResult) message,
						testPlanFromRepo);
			} else if (message instanceof TestPlanScriptResult) {
				updateTestPlanScriptResult((TestPlanScriptResult) message,
						testPlanFromRepo);
			}
		}

	}

	private void updateTestPlanScriptResult(TestPlanScriptResult message,
			TestPlan testPlanFromRepo) {
		try {
			TestPlanScript testPlanScriptFromRepo = testPlanFromRepo
					.extracSpecifiedScript(message.getTestPlanScript()
							.getScriptId());
			testPlanScriptFromRepo.getTestPlanScriptResults().add(message);
		} catch (Exception e) {
			logger.info(ExceptionLog.getStackTrace(e));
		}
	}

	private void updateTestplanMonitorResult(MonitorResult monitorResult,
			TestPlan testPlanFromRepo) {
		try {
			Monitor monitorFromRepo = testPlanFromRepo
					.extractSpecifiedMonitor(monitorResult.getMonitor()
							.getHostName());
			monitorFromRepo.getResults().add(monitorResult);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	private boolean saveUpdatedResult(TestPlan testPlan, Session session) {
		try {
			getTestPlanRepository().doUpdateEntity(session, testPlan);
			return true;
		} catch (Exception e) {
			logger.info(ExceptionLog.getStackTrace(e));
			return false;
		}
	}

}
