package leigh.mud.engine.io;

import leigh.mecha.log.MechaLogger;
import leigh.mecha.log.MechaLoggerFactory;
import leigh.mud.engine.Direction;
import leigh.mud.engine.Exit;
import leigh.mud.engine.Extra;
import leigh.mud.engine.Room;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.file.Path;
import java.util.Collection;
import java.util.HashMap;

/**
 * Class to import CSV-format worldfiles. This is a homegrown creation that is intended to bootstrap the mud
 * world prior to having a proper database.
 *
 * @author Alex Leigh
 */
public class DataImporter {
    private static final MechaLogger logger = MechaLoggerFactory.getLogger(DataImporter.class);

    private final HashMap<Integer, Room> rooms = new HashMap<>();

    public void readExits(Path exitsCsv) throws IOException {
        try (final Reader reader = new InputStreamReader(new FileInputStream(exitsCsv.toFile()))) {
            try (CSVParser parser = new CSVParser(reader, CSVFormat.EXCEL.withHeader());) {
                for (CSVRecord record : parser) {
                    String roomId = record.get("SRC");
                    String dst = record.get("DST");
                    String title = record.get("DIR");
                    String desc = record.get("DESC");

                    Integer srcId = Integer.parseInt(roomId.trim());
                    Room src = rooms.get(srcId);

                    if (src == null) {
                        logger.warn("Missing room for exit! [src: {}] [dst: {}]", roomId, dst);
                        continue;
                    }

                    Direction dir = Direction.getDirection(title);

                    src.getExits().put(dir, new Exit(Integer.parseInt(dst.trim()), desc));
                }
            }
        }
    }

    public void readRooms(Path roomsCsv) throws IOException {
        try (final Reader reader = new InputStreamReader(new FileInputStream(roomsCsv.toFile()))) {
            try (CSVParser parser = new CSVParser(reader, CSVFormat.EXCEL.withHeader());) {
                for (CSVRecord record : parser) {
                    String roomId = record.get("ROOM_ID");
                    String title = record.get("TITLE");
                    String desc = record.get("DESC");
                    Room r = new Room(Integer.parseInt(roomId.trim()), title, desc);
                    rooms.put(r.getId(), r);
                }
            }
        }
    }


    public void readExtras(Path extrasCsv) throws IOException {
        try (final Reader reader = new InputStreamReader(new FileInputStream(extrasCsv.toFile()))) {
            try (CSVParser parser = new CSVParser(reader, CSVFormat.EXCEL.withHeader());) {
                for (CSVRecord record : parser) {
                    String roomId = record.get("ROOM_ID");
                    String nouns = record.get("NOUN");
                    String desc = record.get("DESC");

                    Integer srcId = Integer.parseInt(roomId.trim());
                    Room src = rooms.get(srcId);

                    if (src == null) {
                        logger.warn("Missing room for extra! [room_id: {}]", roomId);
                        continue;
                    }

                    nouns = nouns.replace("~", "");
                    String n[] = nouns.split(" ");

                    Extra ex = new Extra(desc);

                    for (String noun : n) {
                        src.getExtras().put(noun, ex);
                    }
                }
            }
        }
    }


    public Collection<Room> getRooms() {
        return rooms.values();
    }
}