package leigh.minecraft.asuka;

import leigh.mecha.log.MechaLogger;
import leigh.mecha.log.MechaLoggerFactory;
import leigh.mecha.util.StringAccumulatorV2;
import leigh.mecha.util.VelocityWatch;
import leigh.minecraft.BlockUtils;
import org.bukkit.World;
import org.bukkit.block.Block;

import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Locale;

/**
 * Perform an Asuka land survey.
 *
 * @author Alex Leigh
 */
public class AsukaThread implements Runnable {
    private static final MechaLogger logger = MechaLoggerFactory.getLogger(AsukaThread.class);

    private final World world;
    private final int startX = 0;
    private final int startZ = 0;
    private final int size = 1000;

    public AsukaThread(World world) {
        this.world = world;
    }


    @Override
    public void run() {
        VelocityWatch vw = new VelocityWatch(logger);

        try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("asuka.csv"))) {
            StringAccumulatorV2 sa = new StringAccumulatorV2(",");
            sa.add("X");
            sa.add("Y");
            sa.add("Z");
            sa.add("Z_NEG");
            sa.add("LOW_Y");
            sa.add("TEMP");
            sa.add("HUMID");
            sa.add("TYPE");
            sa.add("LOW_TYPE");
            sa.writeLine(bos);

            for (int xi = startX; xi < startX + size; xi++) {
                for (int zi = startZ; zi < startZ + size; zi++) {
                    Block b = world.getHighestBlockAt(xi, zi);
                    Block lowBlock = b;

                    // Attempt to descend to the first non-tree block
                    while ((BlockUtils.isTree(lowBlock.getType().name().toLowerCase(Locale.ROOT)) ||
                            BlockUtils.isAir(lowBlock.getType().name().toLowerCase(Locale.ROOT))) && lowBlock.getY() >= 0) {
                        lowBlock = world.getBlockAt(xi, lowBlock.getY() - 1, zi);
                    }

                    sa.add(Integer.toString(xi));
                    sa.add(Integer.toString(b.getY()));
                    sa.add(Integer.toString(zi));
                    sa.add(Integer.toString(Math.negateExact(zi)));

                    sa.add(Integer.toString(lowBlock.getY()));
                    sa.add(Double.toString(b.getTemperature()));
                    sa.add(Double.toString(b.getHumidity()));
                    sa.add(b.getBiome().name());
                    sa.add(b.getType().name());
                    sa.add(lowBlock.getType().name());

                    sa.writeLine(bos);
                    sa.clear();
                    vw.event("asuka_sample");
                }
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        vw.status();
    }
}
