package de.duehl.basics.text.xml.own;

/*
 * Copyright 2021 Christian Dühl. All rights reserved.
 *
 * This program is free software. You can redistribute it and/or
 * modify it under the same terms as perl:
 *
 * general:  http://dev.perl.org/licenses/
 * GPL:      http://dev.perl.org/licenses/gpl1.html
 * artistic: http://dev.perl.org/licenses/artistic.html
 */

import static org.junit.Assert.*;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

import de.duehl.basics.collections.CollectionsHelper;
import de.duehl.basics.io.FileHelper;
import de.duehl.basics.test.TestHelper;
import de.duehl.basics.text.Text;
import de.duehl.basics.text.xml.own.data.Obstsorte;

public class XmlStorableIOTest {

    private final String path;

    public XmlStorableIOTest() {
        TestHelper testHelper = TestHelper.createForBasics(getClass(), 8);
        path =  testHelper.getTestDataPath() + File.separator;
    }


    /* -------------------------- TESTS -------------------------- */


    @Test
    public void createSaveLines() {
        String xmlCollectionTag = "obstsorten";
        XmlStorableIO xmlIO = new XmlStorableIO(xmlCollectionTag);
        xmlIO.addStorable(new Obstsorte("Apfel"));
        xmlIO.addStorable(new Obstsorte("Banane"));
        xmlIO.addStorable(new Obstsorte("Orange"));
        List<String> lines = xmlIO.createSaveLines();

        assertEquals(11, lines.size());
        assertEquals("<obstsorten>", lines.get(0));
        assertEquals("    <obstsorte>", lines.get(1));
        assertEquals("        <name>Apfel</name>", lines.get(2));
        assertEquals("    </obstsorte>", lines.get(3));
        assertEquals("    <obstsorte>", lines.get(4));
        assertEquals("        <name>Banane</name>", lines.get(5));
        assertEquals("    </obstsorte>", lines.get(6));
        assertEquals("    <obstsorte>", lines.get(7));
        assertEquals("        <name>Orange</name>", lines.get(8));
        assertEquals("    </obstsorte>", lines.get(9));
        assertEquals("</obstsorten>", lines.get(10));
    }

    @Test
    public void saveReadFileContentPlainAndTestFileContent() {
        String filename = path + "xml_storable_io_testfile_save.txt";
        FileHelper.deleteFileIfExistent(filename);

        String xmlCollectionTag = "obstsorten";
        XmlStorableIO xmlIO = new XmlStorableIO(xmlCollectionTag);
        xmlIO.addStorable(new Obstsorte("Apfel"));
        xmlIO.addStorable(new Obstsorte("Banane"));
        xmlIO.addStorable(new Obstsorte("Orange"));
        xmlIO.save(filename);

        String actual = FileHelper.readFileToString(filename);
        String n = Text.LINE_BREAK;
        String expected = "<obstsorten>" + n
                + "    <obstsorte>" + n
                + "        <name>Apfel</name>" + n
                + "    </obstsorte>" + n
                + "    <obstsorte>" + n
                + "        <name>Banane</name>" + n
                + "    </obstsorte>" + n
                + "    <obstsorte>" + n
                + "        <name>Orange</name>" + n
                + "    </obstsorte>" + n
                + "</obstsorten>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void saveReadFileAndTestFileContent() {
        String filename = path + "xml_storable_io_testfile_save.txt";
        FileHelper.deleteFileIfExistent(filename);

        String xmlCollectionTag = "obstsorten";
        XmlStorableIO xmlIO = new XmlStorableIO(xmlCollectionTag);
        xmlIO.addStorable(new Obstsorte("Apfel"));
        xmlIO.addStorable(new Obstsorte("Banane"));
        xmlIO.addStorable(new Obstsorte("Orange"));
        xmlIO.save(filename);

        List<Obstsorte> fruits = readObstsorten(filename);

        assertEquals(3, fruits.size());
        assertEquals("Apfel", fruits.get(0).getName());
        assertEquals("Banane", fruits.get(1).getName());
        assertEquals("Orange", fruits.get(2).getName());
    }

    @Test
    public void loadFromXmlLines() {
        List<String> xmlLines = CollectionsHelper.buildListFrom(
                "<obstsorten>",
                "    <obstsorte>",
                "        <name>Apfel</name>",
                "    </obstsorte>",
                "    <obstsorte>",
                "        <name>Banane</name>",
                "    </obstsorte>",
                "    <obstsorte>",
                "        <name>Orange</name>",
                "    </obstsorte>",
                "</obstsorten>");

        XmlStorableIO xmlIO = new XmlStorableIO("obstsorten");

        List<Obstsorte> fruits = new ArrayList<>();
        xmlIO.loadFromXmlLines(xmlLines, "obstsorte", line -> {
            String name = OwnXmlHelper.readContentOfSingleUniqueXmlElementInXmlLine(
                    "name", line);
            fruits.add(new Obstsorte(name));
        });

        assertEquals(3, fruits.size());
        assertEquals("Apfel", fruits.get(0).getName());
        assertEquals("Banane", fruits.get(1).getName());
        assertEquals("Orange", fruits.get(2).getName());
    }

    @Test
    public void loadFromMultipleXmlLines() {
        List<String> xmlLines = CollectionsHelper.buildListFrom(
                "<obstsorten>\n",
                "    <obstsorte>\n",
                "        <name>Apfel</name>\n",
                "    </obstsorte>\n",
                "    <obstsorte>\n",
                "        <name>Banane</name>\n",
                "    </obstsorte>\n",
                "    <obstsorte>\n",
                "        <name>Orange</name>\n",
                "    </obstsorte>\n",
                "</obstsorten>");

        XmlStorableIO xmlIO = new XmlStorableIO("obstsorten");

        List<Obstsorte> fruits = new ArrayList<>();
        xmlIO.loadFromXmlLines(xmlLines, "obstsorte", line -> {
            String name = OwnXmlHelper.readContentOfSingleUniqueXmlElementInXmlLine(
                    "name", line);
            fruits.add(new Obstsorte(name));
        });

        assertEquals(3, fruits.size());
        assertEquals("Apfel", fruits.get(0).getName());
        assertEquals("Banane", fruits.get(1).getName());
        assertEquals("Orange", fruits.get(2).getName());
    }

    @Test
    public void load() {
        String filename = path + "xml_storable_io_testfile_load.txt";
        List<Obstsorte> fruits = readObstsorten(filename);

        assertEquals(3, fruits.size());
        assertEquals("Apfel", fruits.get(0).getName());
        assertEquals("Banane", fruits.get(1).getName());
        assertEquals("Orange", fruits.get(2).getName());
    }

    private List<Obstsorte> readObstsorten(String filename) {
        String xmlCollectionTag = "obstsorten";
        String xmlDataTag = "obstsorte";

        List<Obstsorte> fruits = new ArrayList<>();
        XmlStorableIO xmlIo = new XmlStorableIO(xmlCollectionTag);
        xmlIo.load(filename, xmlDataTag, line -> {
            String name = OwnXmlHelper.readContentOfSingleUniqueXmlElementInXmlLine(
                    "name", line);
            fruits.add(new Obstsorte(name));
        });

        return fruits;
    }

}
