package com.swandiggy.poe4j.ggpkg;

import com.swandiggy.poe4j.Poe4jException;
import com.swandiggy.poe4j.ggpkg.factory.RecordFactory;
import com.swandiggy.poe4j.ggpkg.record.DirectoryRecord;
import com.swandiggy.poe4j.ggpkg.record.FileRecord;
import com.swandiggy.poe4j.ggpkg.record.Record;
import com.swandiggy.poe4j.util.aspect.MonitorRuntime;
import com.swandiggy.poe4j.util.collection.Node;
import com.swandiggy.poe4j.util.io.BinaryReader;
import com.swandiggy.poe4j.util.io.RafBinaryReader;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * Factory for {@link Ggpk}.
 *
 * @author Jacob Swanson
 * @since 8/31/2015
 */
@Slf4j
public class GgpkFactory {

    @Setter
    private RecordFactory[] recordFactories;

    public GgpkFactory() {
    }

    public GgpkFactory(RecordFactory[] recordFactories) {
        Assert.notEmpty(recordFactories);

        this.recordFactories = recordFactories;
    }

        /**
         * Parse a GGPKG's record structure.
         *
         * @param ggpkgFile Content.ggpk
         * @return Ggpk record structure
         */
    @MonitorRuntime("Loaded records in %f seconds")
    public Ggpk load(File ggpkgFile) {
        Assert.notNull(ggpkgFile);
        Assert.isTrue(ggpkgFile.exists(), "ggpkgFile did not exist");

        log.info("Loading '" + ggpkgFile + "'");

        Map<Long, Record> records = new HashMap<>();

        // Extract records
        try (BinaryReader br = new RafBinaryReader(ggpkgFile, "r")) {
            while (br.getPosition() < br.length()) {
                long recordOffset = br.getPosition();
                int recordLength = br.readInt();

                String tag = br.readString(4);
                Optional<RecordFactory> factory = Arrays.stream(recordFactories)
                        .filter(recordFactory -> recordFactory.supports(tag))
                        .findAny();

                if (!factory.isPresent()) {
                    throw new RuntimeException("No factory for tag: '" + tag + "'");
                }

                records.put(recordOffset, factory.get().read(br, recordOffset, recordLength));
            }
        } catch (IOException e) {
            throw new Poe4jException("Could not close reader", e);
        }

        // Create all of the nodes for the directory structure
        Map<Long, Node<Record>> nodes = new HashMap<>();
        records.values().stream()
                .filter(record -> record instanceof FileRecord || record instanceof DirectoryRecord)
                .map(Node::new)
                .forEach(recordNode -> nodes.put(recordNode.getData().getRecordStart(), recordNode));

        // Connect all of the nodes together
        nodes.values().stream()
                .filter(recordNode -> recordNode.getData() instanceof DirectoryRecord)
                .forEach(recordNode -> {
                    for (DirectoryRecord.DirectoryEntry directoryEntry : ((DirectoryRecord) recordNode.getData()).getEntries()) {
                        Node<Record> childNode = nodes.get(directoryEntry.getRecordStart());
                        recordNode.addChild(childNode);
                        childNode.setParent(recordNode);
                    }
                });

        return new Ggpk(records, ggpkgFile, nodes);
    }
}

@@ -1275,20 +1275,12 @@
     
-    /**%0A    
+/**%0A
     
@@ -1316,20 +1316,16 @@
 ucture.%0A
-    
      *%0A 
@@ -1328,20 +1328,16 @@
  *%0A     
-    
 * @param
@@ -1365,20 +1365,16 @@
 pk%0A     
-  
-  
 * @retur
@@ -1393,28 +1393,24 @@
 d structure%0A
-    
      */%0A    

Fix weird indentation