//============================================================================
//  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.
//
//============================================================================

#include <fides/DataSetReader.h>
#include <vtkm/cont/CellSetExtrude.h>
#include <vtkm/cont/ColorTable.h>
#include <vtkm/filter/clean_grid/CleanGrid.h>

#ifdef USE_VTKM_RENDERING
#include <vtkm/rendering/Camera.h>
#include <vtkm/rendering/CanvasRayTracer.h>
#include <vtkm/rendering/MapperPoint.h>
#include <vtkm/rendering/Scene.h>
#include <vtkm/rendering/View3D.h>
#endif
#include <vtkm/io/VTKDataSetWriter.h>

#ifdef FIDES_USE_MPI
#include <mpi.h>
#endif

#include <string>
#include <unordered_map>
#include <vector>

// This example has 3d data read using SST. This example will also work using BP4 streaming,
// just comment out the lines setting SST engine (Fides will use BP4 if no other engine specified).
int main(int argc, char** argv)
{
  int rank = 0, numRanks = 1;
#ifdef FIDES_USE_MPI
  MPI_Init(&argc, &argv);
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  MPI_Comm_size(MPI_COMM_WORLD, &numRanks);
#endif

  int numBlocks = 8;
  int nPer = numBlocks / numRanks;
  int b0 = rank * nPer;
  int b1 = (rank + 1) * nPer;
  if (rank == numRanks - 1)
    b1 = numBlocks;

  fides::metadata::Vector<std::size_t> blockSelection;
  for (int b = b0; b < b1; b++)
    blockSelection.Data.push_back(b);
  std::cout << rank << ":: " << b0 << " " << b1 << std::endl;

  std::string fname = "./out.bp";
  std::string jsonFile = "../fides/examples/reader_writer/dataset.json";
  if (argc == 3)
  {
    jsonFile = argv[1];
    fname = argv[2];
  }

  //fides::io::DataSetReader reader(fname, "fides/schema");
  fides::io::DataSetReader reader(jsonFile);
  std::unordered_map<std::string, std::string> paths;
  paths["source"] = fname;

  fides::DataSourceParams params;
  //params["engine_type"] = "BPFile";
  params["engine_type"] = "SST";
  reader.SetDataSourceParameters("source", params);

  size_t step = 0;
  while (true)
  {
    auto status = reader.PrepareNextStep(paths);
    if (status == fides::StepStatus::NotReady)
    {
      std::cout << "Not ready...." << std::endl;
      continue;
    }
    else if (status == fides::StepStatus::EndOfStream)
    {
      std::cout << "Stream is done" << std::endl;
      break;
    }

    fides::metadata::MetaData selections;
    selections.Set(fides::keys::BLOCK_SELECTION(), blockSelection);

    auto output = reader.ReadDataSet(paths, selections);
    if (rank == 0)
    {
      std::cout << "Step: " << step << " #ds= " << output.GetNumberOfPartitions() << std::endl;
      //output.PrintSummary(std::cout);
      //std::cout<<std::endl<<std::endl<<std::endl;
    }

    step++;
  }

#ifdef FIDES_USE_MPI
  MPI_Finalize();
#endif

  return 0;
}
