import au.com.bytecode.opencsv.CSVWriter
import au.com.bytecode.opencsv.CSVReader

/**
 * Provides some csv import/export methods.
 * Requires the opencsv jar to be available which is included in the grails-export plugin.
 */
class CsvService {

    boolean transactional = false

    /**
    * Import an asset tree for a single asset.
    * @param file A csv file containing the asset tree for a single asset.
    */
    def importAssetTree(request) {
        def result = [:]

        def megaByteMultiplier = 1000 * 1000
        def fileMaxSize = 10 * megaByteMultiplier //Mb

        def fail = { Map m ->
            //status.setRollbackOnly()
            result.error = [ code: m.code, args: ["Import Asset Tree"] ]
            return result
        }

        def multiPartFile = request.getFile('file')

        if(!multiPartFile || multiPartFile.isEmpty())
            return fail(code: "asset.tree.import.file.not.supplied")

        if (multiPartFile.getSize() > fileMaxSize)
            return fail(code: "asset.tree.import.file.over.max.size")

        InputStreamReader sr = new InputStreamReader(multiPartFile.inputStream)
        CSVReader reader = new CSVReader(sr)

        def nextLine = reader.readNext()
        def lineNumber = 1

        def header = ["Site", "Section", "Asset", "Sub Asset", "Functional Assembly", "Sub Assembly Group"]
        if(nextLine != header)
            return fail(code: "asset.tree.import.no.header")

        nextLine = reader.readNext()
        lineNumber ++

        while(nextLine) {
            lineNumber ++

            println lineNumber + " : " + nextLine[0]

//             if(nextLine[0]) {
//                 if( !Site.findByName(nextLine[0].toString()) )
//                     println nextLine[0]
//             }

            nextLine = reader.readNext()
        } //while(nextLine)

        // Success.
        return result

    } // end importAssetTree()

    /**
    * Build an asset tree template csv file.
    * This template can then be populated for import.
    * @returns The template as a String in csv format.
    */
    def buildAssetTreeTemplate() {

        StringWriter sw = new StringWriter()
        CSVWriter writer = new CSVWriter(sw)

        //Header
        def header = ["Site", "Section", "Asset", "Sub Asset", "Functional Assembly", "Sub Assembly Group"]
        writer.writeNext(header as String[])

        //Rows
        def row

        row = []
        writer.writeNext(row as String[]) //blank row between assets.

        writer.close()
        return sw.toString()
    }

    /**
    * Build complete asset trees for export.
    * @param assetList The list of assets to build and export trees for.
    * @returns The tree as a String in csv format.
    */
    def buildAssetTree(List assetList) {

        StringWriter sw = new StringWriter()
        CSVWriter writer = new CSVWriter(sw)

        //Header
        def header = ["Site", "Section", "Asset", "Sub Asset", "Functional Assembly", "Sub Assembly Group"]
        writer.writeNext(header as String[])

        //Rows
        def row

        def writeAssetSubItem4 = { assetSubItem ->
            row.add(assetSubItem)
            writer.writeNext(row as String[])
        }

        def writeAssetSubItem3 = { assetSubItem ->
            row.add(assetSubItem)

            if(assetSubItem.subItems.size() > 0) {
                assetSubItem.subItems.sort { p1, p2 -> p1.name.compareToIgnoreCase(p2.name) }.each() { assetSubItem4 ->
                    writeAssetSubItem4(assetSubItem4)
                    row.remove(row.last())
                }
            }
            else {
                writer.writeNext(row as String[])
            }

        }

        def writeAssetSubItem2 = { assetSubItem ->
            row.add(assetSubItem)

            if(assetSubItem.subItems.size() > 0) {
                assetSubItem.subItems.sort { p1, p2 -> p1.name.compareToIgnoreCase(p2.name) }.each() { assetSubItem3 ->
                    writeAssetSubItem3(assetSubItem3)
                    row.remove(row.last())
                }
            }
            else {
                writer.writeNext(row as String[])
            }

        }

        def writeAssetSubItem1 = { assetSubItem ->
            row.add(assetSubItem)

            if(assetSubItem.subItems.size() > 0) {
                assetSubItem.subItems.sort { p1, p2 -> p1.name.compareToIgnoreCase(p2.name) }.each() { assetSubItem2 ->
                    writeAssetSubItem2(assetSubItem2)
                    row.remove(row.last())
                }
            }
            else {
                writer.writeNext(row as String[])
            }

        }

        assetList.sort { p1, p2 -> p1.name.compareToIgnoreCase(p2.name) }.each() { asset ->
            row = []
            writer.writeNext(row as String[]) //blank row between assets.
            row.add(asset.section.site)
            row.add(asset.section)
            row.add(asset.name)

            if(asset.assetSubItems.size() > 0) {
                asset.assetSubItems.each() { assetSubItem1 ->
                    writeAssetSubItem1(assetSubItem1)
                    row.remove(row.last())
                }
            }
            else {
                writer.writeNext(row as String[])
            }

        }

        writer.close()
        return sw.toString()
    } // end buildAssetTree

} // end class