/*
 * Copyright 2013 Haulmont
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package smoketest;

import com.haulmont.yarg.formatters.ReportFormatter;
import com.haulmont.yarg.formatters.factory.DefaultFormatterFactory;
import com.haulmont.yarg.formatters.factory.FormatterFactoryInput;
import com.haulmont.yarg.formatters.impl.doc.connector.OfficeIntegration;
import com.haulmont.yarg.structure.BandData;
import com.haulmont.yarg.structure.BandOrientation;
import com.haulmont.yarg.structure.ReportOutputType;
import com.haulmont.yarg.structure.impl.ReportFieldFormatImpl;
import com.haulmont.yarg.structure.impl.ReportTemplateImpl;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.junit.Test;

import java.io.File;
import java.io.FileOutputStream;
import java.util.*;

public class FormattersSmokeTest extends AbstractFormatSpecificTest {
    @Test
    public void testXls() throws Exception {
        BandData root = createRootBand();
        BandData date = new BandData("Date", root);
        BandData dateHeader = new BandData("DateHeader", root);
        date.addData("date", new Date());
        root.addChild(dateHeader);
        root.addChild(date);
        List<BandData> band1objects = root.getChildrenByName("Band1");
        for (int i = 0; i < band1objects.size(); i++) {
            BandData bandData = band1objects.get(i);
            if (i % 2 == 0) {
                bandData.addData("theStyle", "red");
            }
        }

        FileOutputStream outputStream = new FileOutputStream("./result/smoke/result.xls");

        ReportFormatter formatter = new DefaultFormatterFactory().createFormatter(new FormatterFactoryInput("xls", root,
                new ReportTemplateImpl("", "./modules/core/test/smoketest/test.xls", "./modules/core/test/smoketest/test.xls", ReportOutputType.xls), outputStream));

        formatter.renderDocument();

        IOUtils.closeQuietly(outputStream);
    }

    @Test
    public void testXlsToPdf() throws Exception {
        BandData root = createRootBand();

        FileOutputStream outputStream = new FileOutputStream("./result/smoke/result.pdf");

        DefaultFormatterFactory defaultFormatterFactory = new DefaultFormatterFactory();
        defaultFormatterFactory.setOfficeIntegration(new OfficeIntegration(openOfficePath, 8100));
        ReportFormatter formatter = defaultFormatterFactory.createFormatter(new FormatterFactoryInput("xls", root,
                new ReportTemplateImpl("", "./modules/core/test/smoketest/test.xls", "./modules/core/test/smoketest/test.xls", ReportOutputType.pdf), outputStream));

        formatter.renderDocument();

        IOUtils.closeQuietly(outputStream);
    }

    @Test
    public void testDocx() throws Exception {
        BandData root = createRootBand();
        root.addReportFieldFormats(Collections.singletonList(new ReportFieldFormatImpl("Band1.col2", "${html}")));

        BandData footer = root.getChildByName("Footer");
        BandData footerChild = new BandData("FooterChild", footer);
        footerChild.addData("nestedData", "NESTED_DATA");
        footerChild.addData("nestedData.withPoint", "NESTED_DATA_WITH_POINT");
        footer.addChild(footerChild);

        FileOutputStream outputStream = new FileOutputStream("./result/smoke/result.docx");
        ReportFormatter formatter = new DefaultFormatterFactory().createFormatter(new FormatterFactoryInput("docx", root,
                new ReportTemplateImpl("", "./modules/core/test/smoketest/test.docx", "./modules/core/test/smoketest/test.docx", ReportOutputType.docx), outputStream));
        formatter.renderDocument();

        IOUtils.closeQuietly(outputStream);
    }

    @Test
    public void testDocxToPdf() throws Exception {
        BandData root = createRootBand();
        BandData footer = root.getChildByName("Footer");
        BandData footerChild = new BandData("FooterChild", footer);
        footerChild.addData("nestedData", "NESTED_DATA");
        footer.addChild(footerChild);

        FileOutputStream outputStream = new FileOutputStream("./result/smoke/result_docx.pdf");
        DefaultFormatterFactory defaultFormatterFactory = new DefaultFormatterFactory();
        defaultFormatterFactory.setOfficeIntegration(new OfficeIntegration(openOfficePath, 8100));
        ReportFormatter formatter = defaultFormatterFactory.createFormatter(new FormatterFactoryInput("docx", root,
                new ReportTemplateImpl("", "./modules/core/test/smoketest/test.docx", "./modules/core/test/smoketest/test.docx", ReportOutputType.pdf), outputStream));
        formatter.renderDocument();

        IOUtils.closeQuietly(outputStream);
    }

    @Test
    public void testDocxToHtml() throws Exception {
        BandData root = createRootBand();
        root.addReportFieldFormats(Collections.singletonList(new ReportFieldFormatImpl("Band1.col2", "${html}")));

        BandData footer = root.getChildByName("Footer");
        BandData footerChild = new BandData("FooterChild", footer);
        footerChild.addData("nestedData", "NESTED_DATA");
        footer.addChild(footerChild);

        FileOutputStream outputStream = new FileOutputStream("./result/smoke/result_docx.html");
        ReportFormatter formatter = new DefaultFormatterFactory().createFormatter(new FormatterFactoryInput("docx", root,
                new ReportTemplateImpl("", "./modules/core/test/smoketest/test.docx", "./modules/core/test/smoketest/test.docx", ReportOutputType.html), outputStream));
        formatter.renderDocument();

        IOUtils.closeQuietly(outputStream);
    }

    @Test
    public void testDocxToHtml_OfficeIntegration() throws Exception {
        BandData root = createRootBand();
        root.addReportFieldFormats(Collections.singletonList(new ReportFieldFormatImpl("Band1.col2", "${html}")));

        BandData footer = root.getChildByName("Footer");
        BandData footerChild = new BandData("FooterChild", footer);
        footerChild.addData("nestedData", "NESTED_DATA");
        footer.addChild(footerChild);

        FileOutputStream outputStream = new FileOutputStream("./result/smoke/result_docx_office.html");
        DefaultFormatterFactory defaultFormatterFactory = new DefaultFormatterFactory();
        defaultFormatterFactory.setOfficeIntegration(new OfficeIntegration(openOfficePath, 8100));
        ReportFormatter formatter = defaultFormatterFactory.createFormatter(new FormatterFactoryInput("docx", root,
                new ReportTemplateImpl("", "./modules/core/test/smoketest/test.docx", "./modules/core/test/smoketest/test.docx", ReportOutputType.html), outputStream));
        formatter.renderDocument();

        IOUtils.closeQuietly(outputStream);
    }

    @Test
    public void testOdt() throws Exception {
        BandData root = createRootBand();
        root.addReportFieldFormats(Collections.singletonList(new ReportFieldFormatImpl("Band1.col2", "${html}")));

        BandData footer = root.getChildByName("Footer");
        BandData footerChild = new BandData("FooterChild", footer);
        footerChild.addData("nestedData", "NESTED_DATA");
        footer.addChild(footerChild);

        FileOutputStream outputStream = new FileOutputStream("./result/smoke/result.doc");
        DefaultFormatterFactory defaultFormatterFactory = new DefaultFormatterFactory();
        defaultFormatterFactory.setOfficeIntegration(new OfficeIntegration(openOfficePath, 8100));
        ReportFormatter formatter = defaultFormatterFactory.createFormatter(new FormatterFactoryInput("odt", root,
                new ReportTemplateImpl("", "./modules/core/test/smoketest/test.odt", "./modules/core/test/smoketest/test.odt", ReportOutputType.doc), outputStream));
        formatter.renderDocument();

        IOUtils.closeQuietly(outputStream);
    }

    @Test
    public void testDoc() throws Exception {
        BandData root = createRootBand();
        root.addReportFieldFormats(Collections.singletonList(new ReportFieldFormatImpl("Band1.col2", "${html}")));

        BandData footer = root.getChildByName("Footer");
        BandData footerChild = new BandData("FooterChild", footer);
        footerChild.addData("nestedData", "NESTED_DATA");
        footer.addChild(footerChild);

        FileOutputStream outputStream = new FileOutputStream("./result/smoke/result2.doc");
        DefaultFormatterFactory defaultFormatterFactory = new DefaultFormatterFactory();
        defaultFormatterFactory.setOfficeIntegration(new OfficeIntegration(openOfficePath, 8100));
        ReportFormatter formatter = defaultFormatterFactory.createFormatter(new FormatterFactoryInput("doc", root,
                new ReportTemplateImpl("", "./modules/core/test/smoketest/test.doc", "./modules/core/test/smoketest/test.doc", ReportOutputType.doc), outputStream));
        formatter.renderDocument();

        IOUtils.closeQuietly(outputStream);
    }

    @Test
    public void testXlsx() throws Exception {
        BandData root = createRootBand();

        BandData band3_1 = new BandData("Band3", root, BandOrientation.VERTICAL);
        band3_1.addData("col1", 123);
        band3_1.addData("col2", 321);
        BandData band3_2 = new BandData("Band3", root, BandOrientation.VERTICAL);
        band3_2.addData("col1", 456);
        band3_2.addData("col2", 654);
        BandData band3_3 = new BandData("Band3", root, BandOrientation.VERTICAL);
        band3_3.addData("col1", 789);
        band3_3.addData("col2", 987);
        BandData second = new BandData("Second", root, BandOrientation.HORIZONTAL);


        root.addChild(band3_1);
        root.addChild(band3_2);
        root.addChild(band3_3);
        root.addChild(second);

        BandData split = new BandData("Split", root, BandOrientation.HORIZONTAL);
        split.setData(new HashMap<>());
        split.addData("image", FileUtils.readFileToByteArray(new File("./modules/core/test/yarg.png")));
        root.addChild(split);

        FileOutputStream outputStream = new FileOutputStream("./result/smoke/result.xlsx");
        ReportFormatter formatter = new DefaultFormatterFactory().createFormatter(new FormatterFactoryInput("xlsx", root,
                new ReportTemplateImpl("", "./modules/core/test/smoketest/test.xlsx", "./modules/core/test/smoketest/test.xlsx", ReportOutputType.xlsx), outputStream));
        formatter.renderDocument();

        IOUtils.closeQuietly(outputStream);
    }

    @Test
    public void testXlsm() throws Exception {
        BandData root = createRootBand();

        BandData band3_1 = new BandData("Band3", root, BandOrientation.VERTICAL);
        band3_1.addData("col1", 123);
        band3_1.addData("col2", 321);
        BandData band3_2 = new BandData("Band3", root, BandOrientation.VERTICAL);
        band3_2.addData("col1", 456);
        band3_2.addData("col2", 654);
        BandData band3_3 = new BandData("Band3", root, BandOrientation.VERTICAL);
        band3_3.addData("col1", 789);
        band3_3.addData("col2", 987);
        BandData second = new BandData("Second", root, BandOrientation.HORIZONTAL);


        root.addChild(band3_1);
        root.addChild(band3_2);
        root.addChild(band3_3);
        root.addChild(second);

        BandData split = new BandData("Split", root, BandOrientation.HORIZONTAL);
        split.setData(new HashMap<>());
        split.addData("image", FileUtils.readFileToByteArray(new File("./modules/core/test/yarg.png")));
        root.addChild(split);

        FileOutputStream outputStream = new FileOutputStream("./result/smoke/result.xlsm");
        ReportFormatter formatter = new DefaultFormatterFactory().createFormatter(new FormatterFactoryInput("xlsm", root,
                new ReportTemplateImpl("", "./modules/core/test/smoketest/test.xlsx", "./modules/core/test/smoketest/test.xlsm", ReportOutputType.xlsx), outputStream));
        formatter.renderDocument();

        IOUtils.closeQuietly(outputStream);
    }

    @Test
    public void testXlsxToPdf() throws Exception {
        BandData root = createRootBand();

        BandData band3_1 = new BandData("Band3", root, BandOrientation.VERTICAL);
        band3_1.addData("col1", 123);
        band3_1.addData("col2", 321);
        BandData band3_2 = new BandData("Band3", root, BandOrientation.VERTICAL);
        band3_2.addData("col1", 456);
        band3_2.addData("col2", 654);
        BandData band3_3 = new BandData("Band3", root, BandOrientation.VERTICAL);
        band3_3.addData("col1", 789);
        band3_3.addData("col2", 987);
        BandData second = new BandData("Second", root, BandOrientation.HORIZONTAL);


        root.addChild(band3_1);
        root.addChild(band3_2);
        root.addChild(band3_3);
        root.addChild(second);

        BandData split = new BandData("Split", root, BandOrientation.HORIZONTAL);
        split.setData(new HashMap<>());
        split.addData("image", FileUtils.readFileToByteArray(new File("./modules/core/test/yarg.png")));
        root.addChild(split);

        FileOutputStream outputStream = new FileOutputStream("./result/smoke/result_xlsx.pdf");
        DefaultFormatterFactory defaultFormatterFactory = new DefaultFormatterFactory();
        defaultFormatterFactory.setOfficeIntegration(new OfficeIntegration(openOfficePath, 8100));
        ReportFormatter formatter = defaultFormatterFactory.createFormatter(new FormatterFactoryInput("xlsx", root,
                new ReportTemplateImpl("", "./modules/core/test/smoketest/test.xlsx", "./modules/core/test/smoketest/test.xlsx", ReportOutputType.pdf), outputStream));
        formatter.renderDocument();

        IOUtils.closeQuietly(outputStream);
    }

    @Test
    public void testXlsxToHtml() throws Exception {
        BandData root = createRootBand();

        BandData band3_1 = new BandData("Band3", root, BandOrientation.VERTICAL);
        band3_1.addData("col1", 123);
        band3_1.addData("col2", 321);
        BandData band3_2 = new BandData("Band3", root, BandOrientation.VERTICAL);
        band3_2.addData("col1", 456);
        band3_2.addData("col2", 654);
        BandData band3_3 = new BandData("Band3", root, BandOrientation.VERTICAL);
        band3_3.addData("col1", 789);
        band3_3.addData("col2", 987);
        BandData second = new BandData("Second", root, BandOrientation.HORIZONTAL);


        root.addChild(band3_1);
        root.addChild(band3_2);
        root.addChild(band3_3);
        root.addChild(second);

        BandData split = new BandData("Split", root, BandOrientation.HORIZONTAL);
        split.setData(new HashMap<>());
        split.addData("image", FileUtils.readFileToByteArray(new File("./modules/core/test/yarg.png")));
        root.addChild(split);

        FileOutputStream outputStream = new FileOutputStream("./result/smoke/result_xlsx.html");
        DefaultFormatterFactory defaultFormatterFactory = new DefaultFormatterFactory();
        defaultFormatterFactory.setOfficeIntegration(new OfficeIntegration(openOfficePath, 8100));
        ReportFormatter formatter = defaultFormatterFactory.createFormatter(new FormatterFactoryInput("xlsx", root,
                new ReportTemplateImpl("", "./modules/core/test/smoketest/test.xlsx", "./modules/core/test/smoketest/test.xlsx", ReportOutputType.html), outputStream));
        formatter.renderDocument();

        IOUtils.closeQuietly(outputStream);
    }

    @Test
    public void testHtml() throws Exception {
        BandData root = new BandData("Root", null, BandOrientation.HORIZONTAL);
        HashMap<String, Object> rootData = new HashMap<>();
        rootData.put("param1", "AAAAAA");
        root.setData(rootData);

        BandData band11 = new BandData("Band1", root, BandOrientation.HORIZONTAL);
        band11.setData(new RandomMap());

        BandData band12 = new BandData("Band1", root, BandOrientation.HORIZONTAL);
        band12.setData(new RandomMap());

        root.addChild(band11);
        root.addChild(band12);

        FileOutputStream outputStream = new FileOutputStream("./result/smoke/result.html");
        DefaultFormatterFactory defaultFormatterFactory = new DefaultFormatterFactory();
        ReportFormatter formatter = defaultFormatterFactory.createFormatter(new FormatterFactoryInput("html", root,
                new ReportTemplateImpl("", "test.ftl", "./modules/core/test/smoketest/test.ftl", ReportOutputType.html), outputStream));
        formatter.renderDocument();

        IOUtils.closeQuietly(outputStream);
    }


    @Test
    public void testHtmlToPdf() throws Exception {
        BandData root = createRootBand();
        root.addData("date", null);
        root.addData("date2", new Date());
        FileOutputStream outputStream = new FileOutputStream("./result/smoke/result.pdf");
        DefaultFormatterFactory defaultFormatterFactory = new DefaultFormatterFactory();
        defaultFormatterFactory.setFontsDirectory(fontsDirectory);
        ReportFormatter formatter = defaultFormatterFactory.createFormatter(new FormatterFactoryInput("html", root,
                new ReportTemplateImpl("", "test.ftl", "./modules/core/test/smoketest/test.ftl", ReportOutputType.pdf), outputStream));
        formatter.renderDocument();

        IOUtils.closeQuietly(outputStream);
    }

    @Test
    public void testCsv() throws Exception {
        BandData root = new BandData("Root");
        BandData header = new BandData("Header", root);
        BandData first = new BandData("First", root);
        first.addData("firstName", "first");
        first.addData("lastName", "last");
        first.addData("amount", "1");
        BandData second = new BandData("Second", root);
        second.addData("firstName", "second");
        second.addData("lastName", "last 2");
        second.addData("amount", "2");
        root.addChildren(Arrays.asList(header, first, second));

        FileOutputStream outputStream = new FileOutputStream("./result/smoke/result.csv");
        ReportFormatter formatter = new DefaultFormatterFactory().createFormatter(new FormatterFactoryInput("csv", root,
                new ReportTemplateImpl("", "test.csv", "./modules/core/test/smoketest/test.csv", ReportOutputType.csv), outputStream));
        formatter.renderDocument();

        IOUtils.closeQuietly(outputStream);
    }

    @Test
    public void testXlsxToCsv() throws Exception {
        BandData root = createRootBand();

        BandData band3_1 = new BandData("Band3", root, BandOrientation.VERTICAL);
        band3_1.addData("col1", 123);
        band3_1.addData("col2", 321);
        BandData band3_2 = new BandData("Band3", root, BandOrientation.VERTICAL);
        band3_2.addData("col1", 456);
        band3_2.addData("col2", 654);
        BandData band3_3 = new BandData("Band3", root, BandOrientation.VERTICAL);
        band3_3.addData("col1", 789);
        band3_3.addData("col2", 987);
        BandData second = new BandData("Second", root, BandOrientation.HORIZONTAL);

        root.addChild(band3_1);
        root.addChild(band3_2);
        root.addChild(band3_3);
        root.addChild(second);

        BandData split = new BandData("Split", root, BandOrientation.HORIZONTAL);
        split.setData(new HashMap<>());
        split.addData("image", FileUtils.readFileToByteArray(new File("./modules/core/test/yarg.png")));
        root.addChild(split);

        FileOutputStream outputStream = new FileOutputStream("./result/smoke/result_xlsx.csv");
        ReportFormatter formatter = new DefaultFormatterFactory().createFormatter(new FormatterFactoryInput("xlsx", root,
                new ReportTemplateImpl("", "./modules/core/test/smoketest/test.xlsx", "./modules/core/test/smoketest/test.xlsx", ReportOutputType.csv), outputStream));
        formatter.renderDocument();

        IOUtils.closeQuietly(outputStream);
    }
}