import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.List;
import org.junit.jupiter.api.Test;

public class BackendTests {
  // testing getListOfAllLocations methods
  @Test
  public void roleTest1() {
    Graph_Placeholder placeholderGraph = new Graph_Placeholder();
    Backend backend = new Backend(placeholderGraph);
    // insert a new node to the graph
    placeholderGraph.insertNode("Grainger Hall");
    // get all the node in the graph
    List<String> locations = backend.getListOfAllLocations();
    // all the nodes should be in the list
    assertTrue(locations.contains("Union South"));
    assertTrue(locations.contains("Computer Sciences and Statistics"));
    assertTrue(locations.contains("Weeks Hall for Geological Sciences"));
    assertTrue(locations.contains("Grainger Hall"));
  }

  @Test
  public void roleTest2() {
    Backend backend = new Backend(new Graph_Placeholder());

    List<String> path =
        backend.findLocationsOnShortestPath("Union South", "Weeks Hall for Geological Sciences");
    List<Double> times =
        backend.findTimesOnShortestPath("Union South", "Weeks Hall for Geological Sciences");

    // Based on the placeholder's hardcoded path
    assertEquals(List.of("Union South", "Computer Sciences and Statistics",
        "Weeks Hall for Geological Sciences"), path);

    // Based on index positions for getEdge()
    assertEquals(List.of(1.0, 2.0), times);
  }

  @Test
  public void roleTest3() {
    Backend backend = new Backend(new Graph_Placeholder());
    // cuz only the time between union south and computer sciecnes and stat is 1
    List<String> reachable = backend.getReachableFromWithin("Union South", 1.0);
    // the list should only contain computer science and stat
    assertTrue(reachable.contains("Computer Sciences and Statistics"));
    assertFalse(reachable.contains("Weeks Hall for Geological Sciences"));
  }

  @Test
  public void roleTest4() throws IOException {
    String filePath = Paths.get("campus.dot").toAbsolutePath().toString();

    // Create backend using the Graph_Placeholder (or real graph if available)
    Graph_Placeholder graph = new Graph_Placeholder();
    Backend backend = new Backend(graph);

    // Load the file
    backend.loadGraphData(filePath);

    // Retrieve and test locations from the file
    List<String> locations = backend.getListOfAllLocations();
    // cuz we r using placeholder rn
    assertTrue(locations.contains("Union South"));

  }
 @Test
 public void integrationShortestPathTest(){
	DijkstraGraph<String, Double> graph = new DijkstraGraph<>();
	graph.insertNode("A");
	graph.insertNode("B");
	graph.insertEdge("A", "B", 2.0);

	Backend backend = new Backend(graph);

  // Call shortest path methods
	List<String> path = backend.findLocationsOnShortestPath("A", "B");
	List<Double> times = backend.findTimesOnShortestPath("A", "B");

  // Assert correct results
	assertEquals(List.of("A", "B"), path);
	assertEquals(List.of(2.0), times);
	}
/**
 * Integration test to verify reachable nodes within a time limit
 * using the real graph and backend.
 */
@Test
public void testReachableWithinIntegration() {
  DijkstraGraph<String, Double> graph = new DijkstraGraph<>();
  graph.insertNode("X");
  graph.insertNode("Y");
  graph.insertNode("Z");
  graph.insertEdge("X", "Y", 1.0);
  graph.insertEdge("X", "Z", 5.0);

  Backend backend = new Backend(graph);

  // Request reachable nodes from X within 2.0 units
  List<String> reachable = backend.getReachableFromWithin("X", 2.0);

  // Should only include Y, not Z
  assertTrue(reachable.contains("Y"));
  assertFalse(reachable.contains("Z"));
}
/**
 * Integration test to verify behavior when no path exists between nodes.
 */
@Test
public void testNoPathIntegration() {
  DijkstraGraph<String, Double> graph = new DijkstraGraph<>();
  graph.insertNode("A");
  graph.insertNode("B");
  // no edge between A and B

  Backend backend = new Backend(graph);

  List<String> path = backend.findLocationsOnShortestPath("A", "B");
  List<Double> times = backend.findTimesOnShortestPath("A", "B");

  // Should be empty if no path exists
  assertEquals(List.of(), path);
  assertEquals(List.of(), times);
}
/**
 * Integration test to ensure backend chooses the shortest path
 * among multiple options in the graph.
 */
@Test
public void testMultiplePathsIntegration() {
  DijkstraGraph<String, Double> graph = new DijkstraGraph<>();
  graph.insertNode("A");
  graph.insertNode("B");
  graph.insertNode("C");
  graph.insertEdge("A", "B", 1.0);
  graph.insertEdge("B", "C", 1.0);
  graph.insertEdge("A", "C", 5.0);  // longer direct path

  Backend backend = new Backend(graph);

  List<String> path = backend.findLocationsOnShortestPath("A", "C");
  List<Double> times = backend.findTimesOnShortestPath("A", "C");

  // Should take A -> B -> C (total cost 2.0), not A -> C
  assertEquals(List.of("A", "B", "C"), path);
  assertEquals(List.of(1.0, 1.0), times);
}





}
