package io;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;

import data.RepoInfo;
import main.Config;

/**
 * Reads from the xml database
 * 
 * @author Lisa Nguyen Quang Do
 */

public class Reader {
	private final String resultFile;
	private final String worksheetName;

	public Reader(String resultFile, String worksheetName) {
		this.resultFile = resultFile;
		this.worksheetName = worksheetName;
	}

	public Map<Integer, String> getUrls(int columnId, boolean checkCommits) {
		Map<Integer, String> ret = new HashMap<Integer, String>();

		FileInputStream fileInputStream = null;
		Workbook workbook = null;

		try {
			fileInputStream = new FileInputStream(new File(resultFile));
			workbook = WorkbookFactory.create(fileInputStream);
			Sheet sheet = workbook.getSheet(worksheetName);

			Iterator<Row> rowIterator = sheet.iterator();
			while (rowIterator.hasNext()) {
				Row row = rowIterator.next();
				if (row.getRowNum() < Config.firstRow)
					continue;

				if (checkCommits) {
					Cell commitsCell = row.getCell(Config.XML_commitsLastYear);
					if (commitsCell == null || commitsCell.getNumericCellValue() < 1)
						continue;
				}

				Cell cell = row.getCell(columnId);
				ret.put(row.getRowNum(), cell.getStringCellValue());
			}

		} catch (IOException | EncryptedDocumentException | InvalidFormatException e) {
			e.printStackTrace();
		} finally {
			if (fileInputStream != null && workbook != null) {
				try {
					workbook.close();
					fileInputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return ret;
	}

	public Map<Integer, RepoInfo> getSuitableReposInfo() {
		Map<Integer, RepoInfo> reposInfo = new HashMap<Integer, RepoInfo>();

		FileInputStream fileInputStream = null;
		Workbook workbook = null;

		try {
			fileInputStream = new FileInputStream(new File(resultFile));
			workbook = WorkbookFactory.create(fileInputStream);
			Sheet sheet = workbook.getSheet(worksheetName);

			Iterator<Row> rowIterator = sheet.iterator();
			while (rowIterator.hasNext()) {
				Row row = rowIterator.next();
				if (row.getRowNum() < Config.firstRow)
					continue;

				// Suitable -> At least a commit last year
				Cell cell = row.getCell(Config.XML_commitsLastYear);
				if (cell == null || cell.getNumericCellValue() < 1)
					continue;

				cell = row.getCell(Config.XML_potentialBuildTypes);
				if (cell != null && cell.getCellType() != Cell.CELL_TYPE_BLANK)
					continue;

				RepoInfo ri = new RepoInfo();

				cell = row.getCell(Config.XML_url);
				ri.url = cell.getStringCellValue();

				cell = row.getCell(Config.XML_sha);
				ri.sha = cell.getStringCellValue();

				cell = row.getCell(Config.XML_id);
				ri.id = cell.getStringCellValue();

				cell = row.getCell(Config.XML_name);
				ri.name = cell.getStringCellValue().replace(" ", "");

				reposInfo.put(row.getRowNum(), ri);
			}

		} catch (IOException | EncryptedDocumentException | InvalidFormatException e) {
			e.printStackTrace();
		} finally {
			if (fileInputStream != null && workbook != null) {
				try {
					workbook.close();
					fileInputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return reposInfo;
	}

	public Map<String, Integer> getWhitelist() {
		Map<String, Integer> whitelist = new HashMap<String, Integer>();

		FileInputStream fileInputStream = null;
		Workbook workbook = null;

		try {
			fileInputStream = new FileInputStream(new File(resultFile));
			workbook = WorkbookFactory.create(fileInputStream);
			Sheet sheet = workbook.getSheet(worksheetName);

			Iterator<Row> rowIterator = sheet.iterator();
			while (rowIterator.hasNext()) {
				Row row = rowIterator.next();

				Cell cell = row.getCell(0);
				String name = cell.getStringCellValue();

				cell = row.getCell(1);
				int level = (int) cell.getNumericCellValue();

				whitelist.put(name, level);
			}

		} catch (IOException | EncryptedDocumentException | InvalidFormatException e) {
			e.printStackTrace();
		} finally {
			if (fileInputStream != null && workbook != null) {
				try {
					workbook.close();
					fileInputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return whitelist;
	}

}
