package org.sidoh.reactor_simulator.service;

import org.sidoh.reactor_simulator.simulator.BigReactorSimulator;
import org.sidoh.reactor_simulator.simulator.FakeReactorWorld;
import org.sidoh.reactor_simulator.simulator.ReactorDefinition;
import org.sidoh.reactor_simulator.simulator.ReactorResult;
import restx.annotations.GET;
import restx.annotations.RestxResource;
import restx.factory.Component;
import restx.security.PermitAll;

import static com.google.common.base.Preconditions.checkArgument;

@Component
@RestxResource
public class SimulatorResource {
  private static final int MAX_NUMBER_OF_TICKS = 100000;

  @PermitAll
  @GET("/simulate")
  public ReactorResult simulate(ReactorDefinition definition) {
    validateReactorDefinition(definition);

    BigReactorSimulator simulator = new BigReactorSimulator(
        definition.isActivelyCooled(),
        MAX_NUMBER_OF_TICKS
    );
    FakeReactorWorld fakeReactorWorld = FakeReactorWorld.makeReactor(
        definition.getLayout(),
        definition.getxSize(),
        definition.getzSize(),
        definition.getHeight()
    );
    ReactorResult rawResult = simulator.simulate(fakeReactorWorld);

    return new ReactorResult()
        .setCoolantTemperature(rawResult.coolantTemperature)
        .setFuelConsumption(rawResult.fuelConsumption)
        // for display purposes
        .setFuelFertility(rawResult.fuelFertility * 100)
        .setFuelHeat(rawResult.fuelHeat)
        .setOutput(rawResult.output)
        .setReactorDefinition(definition)
        .setReactorHeat(rawResult.reactorHeat);
  }

  private static void validateReactorDefinition(ReactorDefinition reactorDefinition) {
    checkArgument(reactorDefinition.getxSize() >= 5, "xSize should be at least 5");
    checkArgument(reactorDefinition.getzSize() >= 5, "zSize should be at least 5");
    checkArgument(reactorDefinition.getHeight() >= 3, "zSize should be at least 3");

    final int layoutSize = (reactorDefinition.getxSize() - 2) * (reactorDefinition.getzSize() - 2);
    checkArgument(
        reactorDefinition.getLayout().length() == layoutSize,
        String.format(
            "layout size for a %dx%d reactor should be %d",
            reactorDefinition.getxSize(),
            reactorDefinition.getzSize(),
            layoutSize
        )
    );
  }
}

@@ -1705,17 +1705,17 @@
 ze() %3E= 
-5
+3
 , %22xSize
@@ -1726,33 +1726,33 @@
 uld be at least 
-5
+3
 %22);%0A    checkArg
@@ -1789,17 +1789,17 @@
 ze() %3E= 
-5
+3
 , %22zSize
@@ -1822,9 +1822,9 @@
 ast 
-5
+3
 %22);%0A
@@ -1905,24 +1905,303 @@
 least 3%22);%0A%0A
+    checkArgument(reactorDefinition.getxSize() %3C= 32, %22xSize should be no larger than 32%22);%0A    checkArgument(reactorDefinition.getzSize() %3C= 32, %22zSize should be no larger than 32%22);%0A    checkArgument(reactorDefinition.getHeight() %3C= 48, %22height should be no larger than 48%22);%0A%0A
     final in

update validation