#ifndef GALAXY_H
#define GALAXY_H

#include <array>
#include <cstdint>
#include <iostream>
#include <ostream>
#include <regex>
#include <set>
#include <stdexcept>
#include <string>
#include <vector>

#include "buysell.h"
#include "yaml-cpp/yaml.h"

// #define MAX_WARPS 6

typedef uint16_t sector_type;

struct sector_warps {
  sector_type sector;  // Yes, for debug
  // std::set<sector_type> warps;  // possibly
  std::set<sector_type> warps;
  // sector_type warps[MAX_WARPS];
  // ports
  // planets
  // ctor that zeros everything out?
  sector_warps();
  void add(sector_type sector);
  // add() that adds warp to end of warps?
  friend std::ostream& operator<<(std::ostream& os, const sector_warps& warps);
  // bool operator==(const sector_warps& rhs) const;
  // void sort(void);
};

/**
 * Find possible trades with these two port types
 *
 * 0 = NONE
 * 1 = GOOD OE trade pair
 * 2 = OK trade pair
 * 3 = FAIR (one buys, one sells)
 *
 * This will probably be expanded in the future to return:
 *    What port(s) to trade with.  (pos, return top 2)
 *
 * @param port1
 * @param port2
 * @return int
 */
int trade_type(port_type port1, port_type port2);
struct trade_type_result {
  int type;
  buysell trades;
};
trade_type_result trade_type_info(port_type port1, port_type port2);

struct port_pair_type {
  int type;
  sector_type s1, s2;
};


struct port {
  sector_type sector;
  uint8_t type;
  uint16_t amount[3];
  uint8_t percent[3];
  bool unknown(void);
  // port();
  friend std::ostream& operator<<(std::ostream& os, const port& p);
};

struct port parse_portcim(const std::string line);

// SPECIAL = 0
// STARDOCK = 9

class Galaxy {
 public:
  Galaxy();
  ~Galaxy();

  void reset(void);
  YAML::Node config;
  YAML::Node meta;

  int burnt_percent;

  // warps;
  // ports;
  std::map<sector_type, port> ports;
  std::map<sector_type, sector_warps> warps;

  void add_warp(sector_warps);
  void add_port(sector_type sector, int port_class);
  void add_port(port);

  void save(void);
  void load(void);

  std::vector<port_pair_type> find_best_trades(void);
  std::vector<port_pair_type> find_trades(sector_type sector,
                                          bool highest = true);
  void sort_port_pair_type(std::vector<port_pair_type>& pptv);

  char game;
  std::string username;
};

#endif