
package ixbrl

import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.Assert._

import java.io.File
import java.io.FileOutputStream
import ixbrl._

class extractorTest {

    @Before
    def setUp: Unit = { }

    @After
    def tearDown: Unit = { }

    // @Test
    def allTest = {
        val  d = new File("./data")
        visitDirectory(d)
    }

    def visitDirectory(d:File):Unit = {
        d.list.foreach(f => {
                val c = new File(d, f)
                if (c.isDirectory()) {
                    visitDirectory(c)
                } else if (f.endsWith(".html")) {
                    action(c,
                           "out/actual/" + f.substring(0, f.length() - 5) + ".xml",
                           new File(d, f.replaceFirst("\\.html", ".predictedOutput")),
                           "out/expected/" + f.substring(0, f.length() - 5) + ".xml",
                           new File(d, f.replaceFirst("\\.html", ".xbrl")),
                           "out/extractor/" + f.substring(0, f.length() - 5) + ".xml"
                    )
                }
            })
    }

    val files = List[String](
        "FAIL-element-ix-nonNumeric-escape-01.html",
          "PASS-attribute-ix-extension-illegalPlacement-01.html",
          "PASS-attribute-ix-format-denominator-01.html",
          "PASS-attribute-ix-format-nonFraction-01.html",
          "PASS-attribute-ix-format-numerator-01.html",
          "PASS-attribute-ix-name-fraction-01.html",
          "PASS-attribute-ix-name-nonFraction-01.html",
          "PASS-attribute-ix-name-nonNumeric-01.html",

          "PASS-attribute-ix-name-tuple-01.html",

          "PASS-attribute-ix-scale-denominator-01.html",
          "PASS-attribute-ix-scale-denominator-04.html",
          "PASS-attribute-ix-scale-nonFraction-01.html",
          "PASS-attribute-ix-scale-nonFraction-04.html",
          "PASS-attribute-ix-scale-numerator-01.html",
          "PASS-attribute-ix-scale-numerator-04.html",
          "PASS-attribute-ix-sign-denominator-01.html",
          "PASS-attribute-ix-sign-nonFraction-01.html",
          "PASS-attribute-ix-sign-numerator-01.html",
          "PASS-element-ix-exclude-complete.html",
          "PASS-element-ix-nonFraction-complete.html",
          "PASS-element-ix-nonFraction-ixt-numcomma.html",
          "PASS-element-ix-nonFraction-ixt-numcommadot.html",
          "PASS-element-ix-nonFraction-ixt-numdotcomma.html",
          "PASS-element-ix-nonFraction-ixt-numspacecomma.html",
          "PASS-element-ix-nonFraction-ixt-numspacedot.html",

          "PASS-element-ix-nonNumeric-complete.html",
          "PASS-element-ix-nonNumeric-escape-02.html",
          "PASS-element-ix-nonNumeric-escape-03.html",
          "PASS-element-ix-nonNumeric-escape-04.html",
          "PASS-element-ix-nonNumeric-escape-05.html",
          "PASS-element-ix-nonNumeric-escape-06.html",

          "PASS-element-ix-nonNumeric-ixt-datedoteu-01.html",
          "PASS-element-ix-nonNumeric-ixt-datedotus-01.html",
          "PASS-element-ix-nonNumeric-ixt-datelonguk-01.html",
          "PASS-element-ix-nonNumeric-ixt-datelongus-01.html",
          "PASS-element-ix-nonNumeric-ixt-dateshortuk-01.html",
          "PASS-element-ix-nonNumeric-ixt-dateshortus-01.html",
          "PASS-element-ix-nonNumeric-ixt-dateslasheu-01.html",
          "PASS-element-ix-nonNumeric-ixt-dateslashus-01.html",
          "PASS-element-ix-tuple-complete.html",

          "PASS-element-link-footnote-02.html",
          "PASS-element-link-footnote-complete.html",
          "PASS-element-link-footnote-footnoteArcrole.html",
          "PASS-element-link-footnote-footnoteLinkRole.html",
          "PASS-element-link-footnote-footnoteRole.html",
          "PASS-element-link-footnote-xhtml-content.html",
          "PASS-element-ordering.html",

          "PASS-ix-denominator-01.html",
          "PASS-ix-denominator-02.html",
          "PASS-ix-denominator-03.html",
    )

    @Test
    def testList = {
        val  d = new File("./data/files")
        for(f <- files) {
            action(new File(d, f),
                   "out/actual/" + f.substring(0, f.length() - 5) + ".xml",
                   new File(d, f.replaceFirst("\\.html", ".predictedOutput")),
                   "out/expected/" + f.substring(0, f.length() - 5) + ".xml",
                   new File(d, f.replaceFirst("\\.html", ".xbrl")),
                   "out/extractor/" + f.substring(0, f.length() - 5) + ".xml"
            )
        }
    }

    def action(ixbrl:File, actualPath:String,
               predictedOutput:File, expectedPath:String,
               extractorOutput:File, extractorOutPath:String):Unit= {
        Console.println(ixbrl)

        val doc = Extractor.readHtmlFile(ixbrl.toString)
        val xbrls = Extractor.toXBRL(doc)
        xbrls.keys.foreach { t =>
            if (t == "") {
                Extractor.openOutFile(actualPath) { (out:FileOutputStream) =>
                    out.write(Extractor.prittyString(xbrls(t)).getBytes)
                }
            } else {
                val outDir = new File(actualPath).getParent
                val outPath = outDir + "/" + t + ".xml"
                Extractor.openOutFile(outPath) { (out:FileOutputStream) =>
                    out.write(Extractor.prittyString(xbrls(t)).getBytes)
                }
            }
        }
        //Extractor.saveFile(xbrl, actualPath)


        try {
            val pre = Extractor.readHtmlFile(predictedOutput.toString)
            Extractor.openOutFile(expectedPath) { (out:FileOutputStream) =>
                out.write(Extractor.prittyString(pre).getBytes)
            }
        } catch {
            case e => println(e.getMessage)
        }
        // Extractor.saveFile(pre, expectedPath)

        try {
            val ext = Extractor.readHtmlFile(extractorOutput.toString)
            Extractor.openOutFile(extractorOutPath) { (out:FileOutputStream) =>
                out.write(Extractor.prittyString(ext).getBytes)
            }
        } catch {
            case e => println(e.getMessage)
        }
    }

    val filesMulti = List[String](
        // "001/FAIL-multi-input-duplicate-context-ids.html",
        // "002/FAIL-multi-input-duplicate-unit-ids.html",
        // "003/PASS-double-input-single-output.html",
        // "004/PASS-multiple-input-multiple-output.html",
        "005/PASS-single-input-double-output.html",
          // "006/PASS-single-input.html",
    )

    @Test
    def testListMulti = {
        val  d = new File("./data/files2")
        for(f <- filesMulti) {
            actionMulti(new File(d, f),
                        "out/actual/" + f.substring(0, f.lastIndexOf("/")) + "/" ,
                        "out/extractor/" + f.substring(0, f.lastIndexOf("/")) + "/"
            )
        }
    }

    def actionMulti(ixbrl:File, actualPath:String, extractorOutPath:String):Unit= {
        Console.println(ixbrl)

        val doc = Extractor.readHtmlFile(ixbrl.toString)
        val xbrls = Extractor.toXBRL(doc)
        xbrls.keys.foreach { t =>
            if (t == "") {
                Extractor.openOutFile(actualPath + "/" + "default.xml") { (out:FileOutputStream) =>
                    out.write(Extractor.prittyString(xbrls(t)).getBytes)
                }
            } else {
                Extractor.openOutFile(actualPath + "/" + t + ".xml") { (out:FileOutputStream) =>
                    out.write(Extractor.prittyString(xbrls(t)).getBytes)
                }
            }
        }

        try {
            val d = ixbrl.getParentFile
            d.list.foreach(f => {
                    // println( (new File(d,f).getAbsolutePath))
                    val outName = (new File(extractorOutPath+f).getAbsolutePath).replaceFirst("\\.xbrl", ".xml")
                    if (f.endsWith(".xbrl")) {
                        val ext = Extractor.readHtmlFile((new File(d,f)).getAbsolutePath)
                        Extractor.openOutFile(outName) { (out:FileOutputStream) =>
                            out.write(Extractor.prittyString(ext).getBytes)
                        }
                    }
                }
            )
        } catch {
            case e => println(e.getMessage)
        }
    }
}