//=========================================================================
//  Copyright (c) Kitware, Inc.
//  All rights reserved.
//  See LICENSE.txt for details.
//
//  This software is distributed WITHOUT ANY WARRANTY; without even
//  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
//  PURPOSE.  See the above copyright notice for more information.
//=========================================================================
#ifndef smtk_simulation_ace3p_Stage_h
#define smtk_simulation_ace3p_Stage_h

// Project includes
#include "smtk/simulation/ace3p/Exports.h"
#include "smtk/simulation/ace3p/JobsManifest.h"
#include "smtk/simulation/ace3p/Metadata.h"

// SMTK includes
#include "smtk/PublicPointerDefs.h"
#include "smtk/model/Resource.h"

#include <boost/filesystem.hpp>

#include <algorithm> // std::find()
#include <string>
#include <vector>

namespace smtk
{
namespace simulation
{
namespace ace3p
{

class SMTKACE3P_EXPORT Stage
{
public:
  Stage()
    : m_description("(null stage)")
    , m_analysisMesh("(null filename)")
    , m_attribute(nullptr)
    , m_model(nullptr)
    , m_jobsManifest(nullptr)
  {
  }

  Stage(
    std::shared_ptr<smtk::attribute::Resource> attribute,
    std::shared_ptr<smtk::model::Resource> model,
    std::shared_ptr<JobsManifest> jobsManifest,
    std::string description,
    const std::vector<std::string>& jobIDs = std::vector<std::string>())
    : m_description(description)
    , m_attribute(attribute)
    , m_model(model)
    , m_jobIDs(jobIDs)
    , m_jobsManifest(jobsManifest)
  {
    if (model == nullptr)
    {
      std::cerr << "WARNING: " << __FILE__ << ":" << __LINE__
                << " creating stage without model resource." << std::endl;
    }
    else if (!model->properties().contains<std::string>(Metadata::METADATA_PROPERTY_KEY))
    {
      std::cerr << "WARNING: " << __FILE__ << ":" << __LINE__ << " model resource missing "
                << smtk::simulation::ace3p::Metadata::METADATA_PROPERTY_KEY << " property"
                << std::endl;
    }
    else
    {
      std::string meshFile = model->properties().at<std::string>(Metadata::METADATA_PROPERTY_KEY);
      boost::filesystem::path fullPath(meshFile);
      m_analysisMesh = fullPath.filename().string();
    }
  }

  std::shared_ptr<smtk::attribute::Resource> attributeResource() const { return m_attribute; }
  std::shared_ptr<smtk::model::Resource> modelResource() const { return m_model; }
  std::string description() const { return m_description; }
  std::string analysisMesh() const { return m_analysisMesh; }
  const std::vector<std::string> jobIds() const { return m_jobIDs; }

  void setDescription(std::string description) { m_description = description; }
  void insertJob(const std::string& jobID) { m_jobIDs.insert(m_jobIDs.begin(), jobID); }

  /**\brief Initializes job id list  */
  void initJobIds(const std::vector<std::string>& jobIDs) { m_jobIDs = jobIDs; }

  bool removeJob(const std::string& jobId)
  {
    std::vector<std::string>::iterator iter = std::find(m_jobIDs.begin(), m_jobIDs.end(), jobId);
    if (iter != m_jobIDs.end())
    {
      m_jobIDs.erase(iter);
      return true;
    }

    return false; // not found
  }

  virtual ~Stage() = default;

protected:
private:
  std::string m_description;
  std::string m_analysisMesh;
  std::shared_ptr<smtk::attribute::Resource> m_attribute;
  std::shared_ptr<smtk::model::Resource> m_model;
  std::vector<std::string> m_jobIDs;

  std::shared_ptr<JobsManifest> m_jobsManifest;
};

} // namespace ace3p
} // namespace simulation
} // namespace smtk

#endif // smtk_simulation_ace3p_Stage_h
