/* Copyright (C) 2023 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main
   SPDX-License-Identifier: GPL-3.0-only
   Authors: Felix Weiglhofer [committer] */
#ifndef CBM_ALGO_BASE_OPTIONS_H
#define CBM_ALGO_BASE_OPTIONS_H

#include <boost/serialization/access.hpp>
#include <boost/serialization/version.hpp>

#include <set>
#include <string>
#include <vector>

#include "Definitions.h"
#include "compat/Filesystem.h"
#include "log.hpp"

namespace cbm::algo
{

  class Options {

  public:
    Options() = default;
    Options(int argc, char** argv);

    fs::path ParamsDir() const { return fParamsDir; }
    const std::string& InputLocator() const { return fInputLocator; }
    fs::path OutputFile() const { return fOutputFile; }
    bool SplitOutputPerTS() const { return fSplitOutputPerTS; }
    severity_level LogLevel() const { return fLogLevel; }
    fs::path LogFile() const { return fLogFile; }
    const std::string& Device() const { return fDevice; }
    const std::string& MonitorUri() const { return fMonitorUri; }
    bool CollectKernelTimes() const { return fCollectKernelTimes; }
    int NumTimeslices() const { return fNumTimeslices; }
    int SkipTimeslices() const { return fSkipTimeslices; }
    const std::string& ChildId() const { return fChildId; }

    const std::vector<Step>& Steps() const { return fRecoSteps; }
    bool HasStep(Step step) const { return std::find(fRecoSteps.begin(), fRecoSteps.end(), step) != fRecoSteps.end(); }
    const std::vector<RecoData>& OutputTypes() const { return fOutputTypes; }
    bool HasOutput(RecoData recoData) const
    {
      return std::find(fOutputTypes.begin(), fOutputTypes.end(), recoData) != fOutputTypes.end();
    }

    const std::vector<fles::Subsystem>& Detectors() const { return fDetectors; }
    bool HasDetector(fles::Subsystem detector) const
    {
      return std::find(fDetectors.begin(), fDetectors.end(), detector) != fDetectors.end();
    }


  private:                   // members
    std::string fParamsDir;  // TODO: can we make this a std::path?
    std::string fInputLocator;
    std::string fOutputFile;
    bool fSplitOutputPerTS = false;
    severity_level fLogLevel;
    std::string fLogFile;
    std::string fDevice;
    std::string fMonitorUri;
    bool fCollectKernelTimes = false;
    int fNumTimeslices       = -1;
    int fSkipTimeslices      = 0;
    std::vector<Step> fRecoSteps;
    std::vector<RecoData> fOutputTypes;
    std::vector<fles::Subsystem> fDetectors;
    std::string fChildId = "00";

  private:  // serialization
    friend class boost::serialization::access;

    template<class Archive>
    void serialize(Archive& ar, const unsigned int /*version*/)
    {
      ar& fParamsDir;
      ar& fInputLocator;
      ar& fOutputFile;
      ar& fSplitOutputPerTS;
      ar& fLogLevel;
      ar& fLogFile;
      ar& fDevice;
      ar& fMonitorUri;
      ar& fCollectKernelTimes;
      ar& fNumTimeslices;
      ar& fSkipTimeslices;
      ar& fRecoSteps;
      ar& fOutputTypes;
      ar& fDetectors;
    }
  };

}  // namespace cbm::algo

#endif