package de.hftstuttgart.dtabackend.utils;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.Path;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.fasterxml.jackson.core.exc.StreamReadException;
import com.fasterxml.jackson.databind.DatabindException;
import com.fasterxml.jackson.databind.ObjectMapper;

import de.hftstuttgart.dtabackend.models.Result;
import de.hftstuttgart.dtabackend.models.ResultSummary;
import de.hftstuttgart.dtabackend.models.TestCompetencyProfile;

import java.io.FileNotFoundException;

public class CompetencyAssessmentUtil {
	private static final Logger LOG = LogManager.getLogger(CompetencyAssessmentUtil.class);
			
	public static String TEST_COMPETENCY_MANIFEST_FILE_NAME="competency-tests.mft";
	
	public static void main(String[] args) throws StreamReadException, DatabindException, MalformedURLException, IOException {
		ResultSummary summary=ExecuteTestUtil.generateResult(Path.of(args[0]), Path.of(args[1]));
        System.out.println(summary.successfulTestCompetencyProfile);
	}
	
	public static float[] sumTestCompetencyProfiles(List<TestCompetencyProfile> testCompetencyProfiles) {
		float[] tcpTotalProfile=new float[TestCompetencyProfile.MAX_COMPETENCY_DIMENSIONS];
		for(TestCompetencyProfile currentProfile: testCompetencyProfiles) {
			tcpTotalProfile=TestCompetencyProfile.competencySum(tcpTotalProfile, currentProfile.competencyAssessments);
		}
		return tcpTotalProfile;
	}
	
	public static float[] sumSuccessfulCompetencyProfiles(List<TestCompetencyProfile> testCompetencyProfiles, ResultSummary resultSummary) {
		float[] sumSuccessful=new float[TestCompetencyProfile.MAX_COMPETENCY_DIMENSIONS];
		for(Result currentResult: resultSummary.results) {
			if(currentResult.state==Result.State.SUCCESS.ordinal()) {
				TestCompetencyProfile currentProfile=new TestCompetencyProfile();
				currentProfile.testPackageName=(currentResult.packageName!=null)?currentResult.packageName:"";
				currentProfile.testClassName=(currentResult.className!=null)?currentResult.className:"";
				currentProfile.testName=(currentResult.name!=null)?currentResult.name:"";
				int testIndex=testCompetencyProfiles.indexOf(currentProfile);
				if(testIndex!=-1) {
					sumSuccessful=TestCompetencyProfile.competencySum(sumSuccessful, testCompetencyProfiles.get(testIndex).competencyAssessments);
				}
			}
		}
		return sumSuccessful;
	}
	
	public static List<TestCompetencyProfile> readTestCompetencyProfiles(Path testPath, String fileName) {
		List<TestCompetencyProfile> testCompetencyProfiles=new ArrayList<TestCompetencyProfile>();
		try {
			BufferedReader testCompetencyManifest=new BufferedReader(new FileReader(new File(testPath.toFile(), fileName)));
			String testEntry=testCompetencyManifest.readLine();
			while(testEntry!=null)
			{
				String[] testEntyComponents=testEntry.split(TestCompetencyProfile.COMPETENCY_SEPARATOR);
				TestCompetencyProfile currentProfile=new TestCompetencyProfile();
				currentProfile.testPackageName=testEntyComponents[0];
				currentProfile.testClassName=testEntyComponents[1];
				currentProfile.testName=testEntyComponents[2];
				for(int competencyIndex=0; competencyIndex<TestCompetencyProfile.MAX_COMPETENCY_DIMENSIONS; competencyIndex++) {
					currentProfile.competencyAssessments[competencyIndex]=Float.valueOf(testEntyComponents[competencyIndex+3]);
				}
				testCompetencyProfiles.add(currentProfile);
				testEntry=testCompetencyManifest.readLine();
			}
			testCompetencyManifest.close();
			LOG.info("Added "+testCompetencyProfiles.size()+" test competency profiles from test competency manifest. Optional agent functionality enabled.");
		} catch (FileNotFoundException e) {
			LOG.info("Test competency manifest file for agent feedback not found. Skipping optional functionality.");
			testCompetencyProfiles=null;
		} catch (IOException e) {
			LOG.info("Test competency manifest file for agent feedback unreadable. Skipping optional functionality.");
			testCompetencyProfiles=null;
		} 
		return testCompetencyProfiles;
	}

	public static String packFloats(float[] array) {
		return IntStream.range(0, array.length)
	            .mapToObj(i -> String.valueOf(array[i]))
	            .collect(Collectors.joining(";"));
	}

}