package org.bench4q.master.domain.service.report;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
import org.bench4q.master.exception.ExceptionLog;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.title.TextTitle;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Element;
import com.lowagie.text.Image;
import com.lowagie.text.Paragraph;
import com.lowagie.text.pdf.PdfWriter;

@Component
public class ReportService {
	public static String Time = "time";
	public static String PDF_FOLDER = "report";
	private ScriptReportService scriptReportService;
	private MonitorReportService monitorReportService;
	private Logger logger = Logger.getLogger(ReportService.class);
	private static int PICTURE_WIDTH = 500;
	private static int PICTURE_HIGHT = 450;

	public ScriptReportService getScriptReportService() {
		return scriptReportService;
	}

	@Autowired
	public void setScriptReportService(ScriptReportService scriptReportService) {
		this.scriptReportService = scriptReportService;
	}

	public MonitorReportService getMonitorReportService() {
		return monitorReportService;
	}

	@Autowired
	public void setMonitorReportService(
			MonitorReportService monitorReportService) {
		this.monitorReportService = monitorReportService;
	}

	public byte[] createReport(UUID testPlanRunID) {
		try {
			if (isReportCreated(testPlanRunID)) {
				return FileUtils.readFileToByteArray(new File(ReportService
						.buildFilePath(testPlanRunID)));
			}
			isFolderExist();
			Document document = new Document();
			PdfWriter.getInstance(document, new FileOutputStream(
					buildFilePath(testPlanRunID)));
			document.open();
			this.getScriptReportService().createScriptsResultsImage(
					testPlanRunID, document);
			this.getMonitorReportService().createMonitorResultImages(
					testPlanRunID, document);
			document.close();
			return FileUtils.readFileToByteArray(new File(
					buildFilePath(testPlanRunID)));
		} catch (Exception e) {
			logger.error(ExceptionLog.getStackTrace(e));
			return null;
		}
	}

	public boolean isReportCreated(UUID testPlanRunID) {
		return new File(buildFilePath(testPlanRunID)).exists();
	}

	public static String buildFilePath(UUID testPlanRunID) {
		return PDF_FOLDER + System.getProperty("file.separator")
				+ testPlanRunID + ".pdf";
	}

	private void isFolderExist() {
		try {
			if (!new File(PDF_FOLDER).isDirectory()) {
				new File(PDF_FOLDER).mkdir();
			}
		} catch (SecurityException e) {
			e.printStackTrace();
		}
	}

	static void addParagraph(String content, Document document)
			throws DocumentException {
		Paragraph paragraph = new Paragraph(content);
		paragraph.setAlignment(Element.ALIGN_CENTER);
		document.add(paragraph);
	}

	public static ByteArrayOutputStream buildChartStream(Document document,
			int seriesCount, List<TimeSeries> timeSeriesArray, String value)
			throws IOException {

		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
		JFreeChart chart = ChartFactory.createTimeSeriesChart(value,
				ReportService.Time, value, buildDataSet(timeSeriesArray), true,
				true, true);
		adjustChartFont(value, chart);

		ChartUtilities.writeChartAsPNG(outputStream, chart, PICTURE_WIDTH,
				PICTURE_HIGHT);
		return outputStream;
	}

	private static void adjustChartFont(String value, JFreeChart chart) {
		Font xfont = new Font("����", Font.CENTER_BASELINE, 14);// X
		Font yfont = new Font("����", Font.CENTER_BASELINE, 14);// Y
		Font kfont = new Font("����", Font.CENTER_BASELINE, 12);//
		Font titleFont = new Font("΢���ź�", Font.CENTER_BASELINE, 16); // title

		chart.setBorderStroke(new BasicStroke(1));
		chart.setBorderVisible(true);
		chart.setBorderPaint(Color.cyan);

		chart.setTitle(new TextTitle(value, titleFont));
		XYPlot plot = chart.getXYPlot();
		plot.getRangeAxis().setLabelFont(yfont);
		plot.getRangeAxis().setTickLabelFont(kfont);
		plot.getDomainAxis().setLabelFont(xfont);
		plot.getDomainAxis().setTickLabelFont(kfont);
		chart.setBackgroundPaint(java.awt.Color.white);
	}

	public static List<TimeSeries> buildSeries(int seriesCount, String mainTitle) {
		List<TimeSeries> timeSeriesArray = new ArrayList<TimeSeries>(
				seriesCount);
		for (int i = 0; i < seriesCount; i++) {
			timeSeriesArray.add(new TimeSeries(mainTitle + "-" + i));
		}
		return timeSeriesArray;
	}

	static TimeSeriesCollection buildDataSet(
			final List<TimeSeries> timeSeriesArray) {
		TimeSeriesCollection lineDataset = new TimeSeriesCollection();
		if (timeSeriesArray == null) {
			return null;
		}
		for (TimeSeries timeSeries : timeSeriesArray) {
			lineDataset.addSeries(timeSeries);
		}
		return lineDataset;
	}

	public static void writeImageIntoPdf(byte[] buffer, Document document)
			throws Exception {
		Image image = Image.getInstance(buffer);
		image.setAlignment(Element.ALIGN_CENTER);
		document.add(image);
	}

}
