
#ifndef Save_h
#define Save_h

#include <string>
#include <vector>

#include "CoordSys.h"
#include "FileSys.h"
#include "Utils.h"

namespace jf {

class Save {
   public:
    std::vector<Point> LoadGpses() {
        std::vector<Point> ret;
        auto l = [&ret](const std::istringstream &iss, int line_num) {
            double lon, lat, alt;
            std::string s = iss.str();
            std::vector<std::string> ss = Utils::Split(s, ',');
            lon = stod(ss[0]);
            lat = stod(ss[1]);
            // alt = stod(ss[2]);
            ret.push_back(Point(lon, lat, -1234));
        };
        FileSys fs;
        // jf_log_info("[Save::LoadGpses] : loading gps, file : {}", MapConfig::gps_file_path);
        fs.ReadByLine(MapConfig::gps_file_path, l);
        return ret;
    }

    template <typename TileType>
    void SaveTile(const TileId &tid, std::string &os) {
        std::string serializeDir = GetSerializeDir<TileType>();
        if (!FileSys::Exist(serializeDir)) {
            FileSys::MkDir(serializeDir);
        }
        FileSys fs;
        fs.Save(GetSerializeDir<TileType>() + TId2SaveName(tid), os, MapConfig::tile_encrypt);
    }

    template <typename TileType>
    static std::string GetSerializeDir() {
        if (MapConfig::serialize_type_json1_binary2 == 1) {
            return TileType::configType::save_dir_json;
        } else if (MapConfig::serialize_type_json1_binary2 == 2) {
            return TileType::configType::save_dir_binary;
        }
        // jf_log_error("assert false : Save::GetSerializeDir");
        return "";
    }

    template <typename TileType>
    bool LoadTile(const TileId &tid, std::string &is) {
        FileSys fs;
        bool succ = fs.Read(GetSerializeDir<TileType>() + TId2SaveName(tid), is, MapConfig::tile_encrypt);
        return succ;
    }

    template <typename TileType>
    void CleanTileFile() {
        FileSys fs;
        fs.CleanDir(GetSerializeDir<TileType>());
    }

   private:
    std::string TId2SaveName(const TileId &tid) { return std::to_string(tid.nLonId) + "," + std::to_string(tid.nLatId); }

    TileId SaveName2TId(const std::string &filename) {
        std::vector<std::string> ss = Utils::Split(filename, ',');
        int lon = stoi(ss[0]);
        int lat = stoi(ss[1]);
        return TileId(lon, lat);
    }
};

}  // namespace jf

#endif
