// Lee un mapa de data/mapas: V E, luego V líneas de coordenadas y E líneas "u v metros".
#ifndef MAP_FILE_H
#define MAP_FILE_H

#include <cstdlib>
#include <fstream>
#include <iostream>
#include <string>
#include <utility>
#include <vector>

#include "graph.h"

struct MapEdge {
    int u;
    int v;
    int meters;
};

// Devuelve V en node_count y las aristas en el orden del archivo. Sale del programa si falla.
inline std::vector<MapEdge> read_map_edges(const std::string& file_name, int& node_count) {
    std::ifstream file(file_name);
    std::size_t edge_count = 0;
    if (!(file >> node_count >> edge_count)) {
        std::cerr << "no se pudo leer " << file_name << "\n";
        std::exit(1);
    }
    double latitude = 0;
    double longitude = 0;
    for (int i = 0; i < node_count; i++) {
        file >> latitude >> longitude;
    }
    std::vector<MapEdge> edges(edge_count);
    for (MapEdge& edge : edges) {
        file >> edge.u >> edge.v >> edge.meters;
    }
    if (!file) {
        std::cerr << "archivo incompleto: " << file_name << "\n";
        std::exit(1);
    }
    return edges;
}

inline Graph read_map(const std::string& file_name) {
    int node_count = 0;
    std::vector<MapEdge> edges = read_map_edges(file_name, node_count);
    Graph graph(node_count);
    for (const MapEdge& edge : edges) {
        graph.add_edge(edge.u, edge.v, edge.meters);
    }
    return graph;
}

// Memoria de las listas: un vector por nodo más su capacidad reservada. No incluye lo que
// agrega el administrador de memoria a cada bloque.
inline std::size_t list_bytes(const Graph& graph) {
    std::size_t bytes = sizeof(Graph) + graph.node_count() * sizeof(std::vector<Edge>);
    for (int u = 0; u < graph.node_count(); u++) {
        bytes += graph.neighbors(u).capacity() * sizeof(Edge);
    }
    return bytes;
}

#endif
