package info.bukova.isspst.reporting;

import info.bukova.isspst.SpringUtils;
import info.bukova.isspst.data.DataModel;
import info.bukova.isspst.data.SignedDocumentItem;
import info.bukova.isspst.services.signeddocs.SignedDocumentService;
import info.bukova.isspst.storage.ReportFileStorage;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.JasperRunManager;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.engine.util.JRLoader;
import net.sf.jasperreports.engine.util.JRProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletContext;
import java.io.File;

@SuppressWarnings("deprecation")
public class PredefinedGenerator implements Generator {
	
	private ReportDefinition definition;
	private ServletContext ctx;
	private final static Logger logger = LoggerFactory.getLogger(PredefinedGenerator.class);

	public PredefinedGenerator(ReportDefinition definition, ServletContext ctx) {
		this.definition = definition;
		this.ctx = ctx;
	}

	@Override
	public byte[] generate() {
		byte[] bytes = null;
		SignedDocumentItem signedItem = getSignedDocument();

		if (signedItem != null) {
			return fromStorage(signedItem);
		}

		try {
			JasperReport report = (JasperReport) JRLoader.loadObject(getReportFile());
			JRProperties.setProperty("net.sf.jasperreports.default.pdf.encoding", "Cp1250");
			loadLazyData();
			definition.setParam("SUBREPORT_DIR", ctx.getRealPath("WEB-INF/reports") + "/");
			bytes = JasperRunManager.runReportToPdf(report, definition.getParams(), new JRBeanCollectionDataSource(definition.getDataSet()));;
		} catch (JRException e) {
			logger.error("Generator error: " + e.getMessage());
			throw new ReportException(e);
		}
		
		return bytes;
	}

	private byte[] fromStorage(SignedDocumentItem sdItem) {
		ReportFileStorage reportStorage = SpringUtils.getBean(ReportFileStorage.class, ctx);
		return reportStorage.fileData(sdItem);
	}

	private SignedDocumentItem getSignedDocument() {
		SignedDocumentService sdService = SpringUtils.getBean(SignedDocumentService.class, ctx);
		SignedDocumentItem sdItem = sdService.getItem((DataModel) definition.getDataSet().get(0), definition.getReport().getReportId());

		return sdItem;
	}
	
	protected File getReportFile() {
		return new File(ctx.getRealPath("WEB-INF/reports") + "/" + definition.getReport().getJasperFile() + ".jasper");
	}
	
	private void loadLazyData() {
		if (definition.getService() == null) {
			return;
		}
		
		for (Object o : definition.getDataSet()) {
			definition.getService().loadLazyData(o);
		}
	}

}
