/**
 * @file FactoryGraphManagerParameters.hpp
 * @author The ARTIS Development Team
 * See the AUTHORS or Authors.txt file
 */

/*
 * ARTIS - the multimodeling and simulation environment
 * This file is a part of the ARTIS environment
 *
 * Copyright (C) 2013-2023 ULCO http://www.univ-littoral.fr
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef ARTIS_FACTORY_FACTORY_GRAPH_MANAGER_PARAMETERS_HPP
#define ARTIS_FACTORY_FACTORY_GRAPH_MANAGER_PARAMETERS_HPP

#include "JsonReader.hpp"

namespace artis::factory {

struct FactoryGraphManagerParameters {
  Factory factory;

  std::map<unsigned int, int> get_item_stock(unsigned int id) const {
    std::map<unsigned int, int> items;

    auto it = std::find_if(factory._stocks.cbegin(), factory._stocks.cend(),
                           [id](const auto &e) { return e._id == id; });
    if (it != factory._stocks.cend()) {
      for (const auto &e: it->_items) {
        items[e._id] = e._quantity;
      }
    }
    return items;
  }

  std::vector<unsigned int> get_machines_to_item_stock(unsigned int id) const {
    std::vector<unsigned int> machines;

    for (const auto &p: factory._products) {
      for (const auto &q: p.second._pool_jobs) {
        for (const auto &r: q._machine_jobs) {
          for (const auto &s: r._ins) {
            if (s._source._stock_id == id and
                std::find(machines.cbegin(), machines.cend(), r._machine_id) == machines.cend()) {
              machines.push_back(r._machine_id);
            }
          }
        }
      }
    }
    return machines;
  }

  std::vector<unsigned int> get_machines_to_in_stock(unsigned int pool_id, unsigned int stock_id) const {
    std::vector<unsigned int> machines;

    for (const auto &p: factory._products) {
      for (const auto &q: p.second._pool_jobs) {
        for (const auto &r: q._machine_jobs) {
          for (const auto &s: r._ins) {
            if (s._source._pool_id == (int) pool_id and s._source._stock_id == stock_id and
                std::find(machines.cbegin(), machines.cend(), r._machine_id) == machines.cend()) {
              machines.push_back(r._machine_id);
            }
          }
        }
      }
    }
    return machines;
  }

  std::vector<unsigned int> get_machines_to_out_stock(unsigned int pool_id, unsigned int stock_id) const {
    std::vector<unsigned int> machines;

    for (const auto &p: factory._products) {
      for (const auto &q: p.second._pool_jobs) {
        for (const auto &r: q._machine_jobs) {
          for (const auto &s: r._outs) {
            if (s._destination._pool_id == (int) pool_id and s._destination._stock_id == stock_id and
                std::find(machines.cbegin(), machines.cend(), r._machine_id) == machines.cend()) {
              machines.push_back(r._machine_id);
            }
          }
        }
      }
    }
    return machines;
  }

  std::map<unsigned int, Program> get_programs() const {
    std::map<unsigned int, Program> programs;

    for (const auto &product: factory._products) {
      unsigned int product_id = product.first;
      Program program;

      for (const auto &pool_job: product.second._pool_jobs) {
        std::vector<uint8_t> machines;

        for (const auto &machine_job: pool_job._machine_jobs) {
          machines.push_back(machine_job._machine_id);
        }
        program.emplace_back((uint8_t) pool_job._pool_id, machines);
      }
      programs[product_id] = program;
    }
    return programs;
  }

};

}

#endif //ARTIS_FACTORY_FACTORY_GRAPH_MANAGER_PARAMETERS_HPP
