//============================================================================
//  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.
//
//  Copyright 2016 Sandia Corporation.
//  Copyright 2016 UT-Battelle, LLC.
//  Copyright 2016 Los Alamos National Security.
//
//  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
//  the U.S. Government retains certain rights in this software.
//
//  Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
//  Laboratory (LANL), the U.S. Government retains certain rights in
//  this software.
//============================================================================

#include <vtkm/filter/CleanGrid.h>

#include <vtkm/cont/testing/MakeTestDataSet.h>
#include <vtkm/cont/testing/Testing.h>

namespace {

void TestUniformGrid()
{
  std::cout << "Testing 'clean' uniform grid." << std::endl;

  vtkm::cont::testing::MakeTestDataSet makeData;

  vtkm::cont::DataSet inData = makeData.Make2DUniformDataSet0();

  vtkm::filter::CleanGrid clean;

  vtkm::filter::ResultDataSet result = clean.Execute(inData);
  VTKM_TEST_ASSERT(result.IsValid(), "Filter failed to execute");

  bool success;
  success = clean.MapFieldOntoOutput(result, inData.GetField("pointvar"));
  VTKM_TEST_ASSERT(success, "Failed to map point field");
  success = clean.MapFieldOntoOutput(result, inData.GetField("cellvar"));
  VTKM_TEST_ASSERT(success, "Failed to map cell field");

  vtkm::cont::DataSet outData = result.GetDataSet();

  vtkm::cont::CellSetExplicit<> outCellSet;
  outData.GetCellSet().CopyTo(outCellSet);
  VTKM_TEST_ASSERT(outCellSet.GetNumberOfPoints() == 6, "Wrong number of points");
  VTKM_TEST_ASSERT(outCellSet.GetNumberOfCells() == 2, "Wrong number of cells");
  vtkm::Vec<vtkm::Id,4> cellIds;
  outCellSet.GetIndices(0, cellIds);
  VTKM_TEST_ASSERT((cellIds == vtkm::Vec<vtkm::Id,4>(0, 1, 4, 3)),
                   "Bad cell ids");
  outCellSet.GetIndices(1, cellIds);
  VTKM_TEST_ASSERT((cellIds == vtkm::Vec<vtkm::Id,4>(1, 2, 5, 4)),
                   "Bad cell ids");

  vtkm::cont::ArrayHandle<vtkm::Float32> outPointField;
  outData.GetField("pointvar").GetData().CopyTo(outPointField);
  VTKM_TEST_ASSERT(outPointField.GetNumberOfValues() == 6,
                   "Wrong point field size.");
  VTKM_TEST_ASSERT(
        test_equal(outPointField.GetPortalConstControl().Get(1), 20.1),
        "Bad point field value");
  VTKM_TEST_ASSERT(
        test_equal(outPointField.GetPortalConstControl().Get(4), 50.1),
        "Bad point field value");

  vtkm::cont::ArrayHandle<vtkm::Float32> outCellField;
  outData.GetField("cellvar").GetData().CopyTo(outCellField);
  VTKM_TEST_ASSERT(outCellField.GetNumberOfValues() == 2,
                   "Wrong cell field size.");
  VTKM_TEST_ASSERT(
        test_equal(outCellField.GetPortalConstControl().Get(0), 100.1),
        "Bad cell field value");
  VTKM_TEST_ASSERT(
        test_equal(outCellField.GetPortalConstControl().Get(1), 200.1),
        "Bad cell field value");
}

void RunTest()
{
  TestUniformGrid();
}

} // anonymous namespace

int UnitTestCleanGrid(int, char *[])
{
  return vtkm::cont::testing::Testing::Run(RunTest);
}
