/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package de.nplusc.izc.iZpl;

import de.nplusc.izc.tools.IOtools.FileTK;
import de.nplusc.izc.tools.baseTools.Tools;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import org.yaml.snakeyaml.Yaml;

/**
 *
 * @author LH
 */
public class PLReader
{
    //Formatdefinition //basiert aufne verpackte #extm3u
    /*
    * #EXTM3U
    * #iZPl
    * #EXTINFO.......//Die VLC-Daten
    * #IZPL:PrioMultiplier|GroupID (IDS !=0 sind Verbunden. 0er immer einzeln)
    * /Pfad/zu/File1.mp3
    * //Defaultet zu 1,0 falls nicht gefunden
    * #IZPL:INCLUDE|PrioMultiplier|Expand//INCLUDE sagt dass hier ne referenzierte IZPL liegt Expand sagt Liste kann aufgeteilt werden
    * /Pfad/zu/andererListe.iZpl //prioMultiplier bei include mutipliziert Multiopliers des Includes
    * #IZPL:INCLUDE|PrioMultiplier|NoExpand //NoExpand sagt dass File Als ein Block behandelt werden muss (Includes innerhalb werden vorläufig nicht beachtet
    * /Pfad/zu/UnsplittbarerListe.iZpl
    */
    private static Yaml yp = new Yaml();
    public static List<String[]> readList(String path)
    {
        return (readList(path,0));
    }
    public static List<String[]> readList(String path,int rd)
    {
        HashMap<Integer,List<String>> GroupStorage = new HashMap<>();
        List<String[]> BloxBuffr = new ArrayList<>();
        List<String[]> mergedLists = new ArrayList<>();
        String[] playListRaw = FileTK.fileload(path);//temporär ne bestimmte hardcoden
        GroupStorage.put(0,new ArrayList<String>());//MUSS_EXISTIEREN!!!
        if(playListRaw.length<2)
        {
            Builder.issueDetected = true;
            return null;
        }
        if(playListRaw[0].equals("#EXTM3U"))//&&playListRaw[1].equals("#IZPL"))//HEaderValidate
        {
            if(!playListRaw[1].equals("#IZPL"))
            {
                String[] block = new String[]{"","",""};
                Tools.DebugHelperPrint(">>EnterPlainPL",true,"izpl.enableFastDebug");
                for (int i = 1; i < playListRaw.length-1; i++)
                {
                    String line = playListRaw[i];
                                        //@blox: 0 ist die extinf;1 die #IZPL-Zone 2 der filename
                    if(line.startsWith("EXTINF:"))
                    {
                        block[0]=line;
                        block[1]="#IZPL:1|0";
                        i++;
                        line = playListRaw[i];
                        block[2]=line;
                        BloxBuffr.add(block);
                        block=new String[3];
                    }
                    else
                    {
                        block[0]="";
                        block[1]="#IZPL:1|0";
                        block[2]=line;
                        BloxBuffr.add(block);
                        block=new String[3];
                    }
                }
            }
            else
            {
                Tools.DebugHelperPrint(">>EnteriIZinkedPL",true,"izpl.enableFastDebug");
                int bstart=0;
                int bl=0;
                String[] block  = new String[3];
                for (int i = 2; i < playListRaw.length-1; i++)
                {

                    String line = playListRaw[i];
                    if(line.startsWith("#EXTINF:"))
                    {
                        bl=3;
                        bstart=i;
                        block[0]=line;//EXTINF wird durchgepipe'd
                    }
                    else
                    {

                        if(bl>0)//IN_BLOCK
                        {
                            int it=i-bstart;
                            Tools.DebugHelperPrint(it+"",true,"izpl.enableFileFormatDebug");

                            block[it]=line;
                            if(bstart+bl-1==i)
                            {
                                BloxBuffr.add(block);
                                block=new String[3];
                                bl=0;
                                bstart=0;
                            }
                        }
                        else//START_BLOCK
                        {
                            bl=0;
                            block[0]="";
                            if(playListRaw[i+1].startsWith("#EXTINF")||playListRaw[i+1].startsWith("#IZPL"))//erkennen von undefineds
                            {
                                block[2]=line;
                                block[1]="#IZPL:1|0";
                            }
                            else
                            {
                            block[1]=line;
                            i++;
                            block[2]=playListRaw[i];
                            }
                            BloxBuffr.add(block);
                            block=new String[3];
                        }
                    }
                }
            }
        }
        int sublistsFound = 0;
        for (String[] blox : BloxBuffr)//0 ist die extinf;1 die #IZPL-Zone 2 der filename
        {
            Tools.DebugHelperPrint("|>"+blox[0]+"\n"+blox[1]+"\n"+blox[2]+"\n",true,"izpl.enableFileFormatDebug");
            String[] metadata = blox[1].substring(6).split("\\|");
            if(metadata[0].equalsIgnoreCase("INCLUDE"))//muss noch nen Detektor für NoExpand einbauen
            {
                System.err.println();
                Tools.DebugHelperPrint("<<< Include",true,"izpl.enableFastDebug");
                if(metadata[2].equalsIgnoreCase("NOEXPAND"))
                {
                    Tools.DebugHelperPrint("<°())))<Include",true,"izpl.enableFastDebug");
                    int priomult=Integer.valueOf(metadata[1].trim());
                    int runs = 0;
                    while(runs<priomult)
                    {
                        sublistsFound++;
                        String lfid = blox[2];
                        if(!lfid.substring(1,2).equals(":"))//absoluterPfad
                        {
                            lfid=FileTK.getFilePath(path)+"\\"+lfid;
                        }
                        Tools.DebugHelperPrint(lfid,true,"izpl.enableFastDebug");
                        List<String[]> subList = readList(lfid,rd+1);
                        Builder.issueDetected=false;//überdeckt Sublisten-Errors bei Rekursion, da dann ja etwas zurückkommt
                        List<String> target = new ArrayList<>();
                        String[] group0 = subList.get(0);
                        target.addAll(Arrays.asList(group0));//merged die Gruppe 0 die einzeleinträge enthält
                        for (int i = 1; i < subList.size(); i++)
                        {
                            target.addAll(Arrays.asList(subList.get(i)));
                        }
                        GroupStorage.put((10000*sublistsFound)+1,target);
                        runs++;
                    }
                    
                }
                else
                {
                    Tools.DebugHelperPrint(">(((()°> Include",true,"izpl.enableFastDebug");
                    int priomult=Integer.valueOf(metadata[1].trim());
                    int runs = 0;
                    while(runs<priomult)
                    {
                        sublistsFound++;
                        String lfid = blox[2];
                        if(!lfid.substring(1,2).equals(":"))//absoluterPfad
                        {
                            lfid=FileTK.getFilePath(path)+"\\"+lfid;
                        }
                        Tools.DebugHelperPrint(lfid,true,"izpl.enableFastDebug");
                        List<String[]> subList = readList(lfid,rd+1);
                        Builder.issueDetected=false;//überdeckt Sublisten-Errors bei Rekursion, da dann ja etwas zurückkommt
                        String[] group0 = subList.get(0);
                        GroupStorage.get(0).addAll(Arrays.asList(group0));//merged die Gruppe 0 die einzeleinträge enthält
                        for (int i = 1; i < subList.size(); i++)
                        {
                           List<String> target = Arrays.asList(subList.get(i));
                           GroupStorage.put((10000*sublistsFound)+i,target);
                        }
                        runs++;
                    }
                    
                }

            }
            else
            {
                int priomult=Integer.valueOf(metadata[0].trim());
                int gid=Integer.valueOf(metadata[1].trim());
                if(!GroupStorage.containsKey(gid))
                {
                    GroupStorage.put(gid,new ArrayList<String>());
                }
                List<String> ge = GroupStorage.get(gid);
                String entry = blox[0]+"\n"+blox[2];
                for (int i = 0; i < priomult; i++)//setzt die Priorität um durch mehrfacheintragung.....
                {
                    Tools.DebugHelperPrint(">>>"+entry,true,"izpl.enableFileFormatDebug");
                    ge.add(entry);
                }
            }
        }
        List<String> gid0 = GroupStorage.get(0);
        GroupStorage.remove(0);
        String[] gtmp = new String[gid0.size()];
        for (int i = 0; i < gid0.size(); i++)
        {
            gtmp[i]= gid0.get(i);
            
        }
        mergedLists.add(gtmp);
        Set<Integer> s = GroupStorage.keySet();
        for (Integer k : s)
        {
           List<String> temp = GroupStorage.get(k); 
           gtmp = new String[temp.size()];
            for (int i = 0; i < gtmp.length; i++)
            {
                gtmp[i]=temp.get(i);
            }
            mergedLists.add(gtmp);
        }
        Tools.DebugHelperPrint("NOP",true,"izpl.enableFastDebug");
        System.out.println("ArrayResult of reading in:"+path);
        System.out.println("Depth:"+rd);
        System.out.println("\n"+yp.dump(mergedLists));//macht das log leichter parsbar in NPP mit Ansicht=yaml
        System.out.println("ENd of Block:"+path);
        System.out.println("###########################################################################");
        System.out.println("---------------------------------------------------------------------------");
        System.out.println("###########################################################################");

        return mergedLists;
    }
    
}
