package org.jassetmanager;

import com.sun.istack.internal.NotNull;

import javax.servlet.ServletContext;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class AssetBundle {
    private byte[] content;
    private boolean built;
    private final ServletContext context;
    private final AssetBundleConfiguration config;
    private static final byte[] ASSET_SEPARATOR = new byte[] { '\r', '\n' };

    public AssetBundle(@NotNull AssetBundleConfiguration config,
                       @NotNull ServletContext context) {

        this.context = context;
        this.config = config;
        this.content = new byte[0];
        this.built = false;
    }

    public boolean isBuilt() {
        return this.built;
    }

    public byte[] getContent() {
        return this.content;
    }

    public void build(@NotNull List<String> allFilePaths) throws IOException {

        this.content = new byte[0];
        this.built = false;
        
        Map<Integer, List<String>> contentMap = new HashMap<Integer, List<String>>();
        int maxPosition = 0;

        for (String filePath : allFilePaths) {
            int position = this.config.getContentPosition(filePath);
            if (position == -1) {
                continue;
            } else if (position > maxPosition) {
                maxPosition = position;
            }

            if (!(contentMap.containsKey(position))) {
                contentMap.put(position, new ArrayList<String>());
            }

            contentMap.get(position).add(filePath);
        }

        for (int position = 0; position <= maxPosition; position++) {
            if (!(contentMap.containsKey(position))) {
                continue;
            }
            
            List<String> filePaths = contentMap.get(position);
            for (String filePath : filePaths) {
                readAndAppendContent(this.context, filePath);
            }
        }

        this.built = true;
    }

    private void readAndAppendContent(ServletContext context, String filePath) throws IOException {
        byte[] buffer = new byte[1024];
        InputStream is = null;

        try {
            is = context.getResourceAsStream(filePath);
            if (is == null) {
                throw new IOException("Could not open stream to asset '" + filePath + "'");
            }

            while (is.available() > 0) {
                int length = is.read(buffer);

                if (length != -1) {
                    appendContent(buffer, length);
                }
            }
        } finally {
            try {
                if (is != null) {
                    is.close();
                }
            } catch (Exception e) {

            }
        }
    }

    private void appendContent(byte[] append, int appendLength) {
        int newContentLength = this.content.length + ASSET_SEPARATOR.length + appendLength;

        byte[] newContent = new byte[newContentLength];
        System.arraycopy(this.content, 0, newContent, 0, this.content.length);
        System.arraycopy(append, 0, newContent, this.content.length, appendLength);
        System.arraycopy(ASSET_SEPARATOR, 0, newContent, (this.content.length + appendLength), ASSET_SEPARATOR.length);

        this.content = newContent;
    }
}

@@ -176,88 +176,9 @@
 til.
-ArrayList;%0Aimport java.util.HashMap;%0Aimport java.util.List;%0Aimport java.util.Map
+*
 ;%0A%0Ap
@@ -899,17 +899,16 @@
 ption %7B%0A
-%0A
         
@@ -963,24 +963,25 @@
  false;%0A
+%0A
         
 %0A       
@@ -964,32 +964,824 @@
 false;%0A%0A        
+Map%3CInteger, List%3CString%3E%3E contentMap = createContentMap(allFilePaths);%0A        readAndAppendFilesFromContentMap(contentMap);%0A        %0A        this.built = true;%0A    %7D%0A%0A    private void readAndAppendFilesFromContentMap(Map%3CInteger, List%3CString%3E%3E contentMap) throws IOException %7B%0A        List%3CInteger%3E keys = new ArrayList%3CInteger%3E(contentMap.keySet());%0A        Collections.sort(keys);%0A%0A        for (Integer position : keys) %7B%0A            List%3CString%3E files = contentMap.get(position);%0A            readAndAppendFiles(files);%0A        %7D%0A    %7D%0A%0A    private void readAndAppendFiles(List%3CString%3E files) throws IOException %7B%0A        for (String file : files) %7B%0A            readAndAppendFile(file);%0A        %7D%0A    %7D%0A%0A    private Map%3CInteger, List%3CString%3E%3E createContentMap(List%3CString%3E allFilePaths) %7B
 %0A        Map%3CInt
@@ -1854,37 +1854,8 @@
 %3E();
-%0A        int maxPosition = 0;
 %0A%0A  
@@ -2045,97 +2045,8 @@
    %7D
- else if (position %3E maxPosition) %7B%0A                maxPosition = position;%0A            %7D
 %0A%0A  
@@ -2255,401 +2255,25 @@
     
-for (int position = 0; position %3C= maxPosition; position++) %7B%0A            if (!(contentMap.containsKey(position))) %7B%0A                continue;%0A            %7D%0A            %0A            List%3CString%3E filePaths = contentMap.get(position);%0A            for (String filePath : filePaths) %7B%0A                readAndAppendContent(this.context, filePath);%0A            %7D%0A        %7D%0A%0A        this.built = true
+return contentMap
 ;%0A  
@@ -2311,40 +2311,13 @@
 pend
-Content(ServletContext context, 
+File(
 Stri
@@ -2449,24 +2449,29 @@
        is = 
+this.
 context.getR
@@ -2780,24 +2780,28 @@
       append
+File
 Content(buff
@@ -3058,16 +3058,20 @@
 d append
+File
 Content(

Divided the code into smaller methods in AssetBundle