//=========================================================================
//  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 "smtk/common/ResourceSet.h"
#include "smtk/attribute/System.h"

#include <iostream>

// Basic tests for smtk::common::ResourceSet

int main(int /* argc */, const char* /* argv */ [])
{
  int status = 0;
  bool result;
  unsigned n;
  smtk::common::ResourceSet resourceSet;

  // Create and add attribute system
  smtk::attribute::SystemPtr system1 = smtk::attribute::System::create();
  result = resourceSet.addResource(system1, "system1", "", smtk::common::ResourceSet::TEMPLATE);
  n = static_cast<unsigned>(resourceSet.numberOfResources());
  if (!result)
  {
    std::cerr << "addResource() call failed" << std::endl;
    status += 1;
  }
  else if (n != 1)
  {
    std::cerr << "Wrong number of resources: " << n << ", should be 1" << std::endl;
    status += 1;
  }

  // Create amd add 2nd attribute system
  smtk::attribute::SystemPtr system2 = smtk::attribute::System::create();
  result =
    resourceSet.addResource(system2, "system2", "path2", smtk::common::ResourceSet::INSTANCE);
  n = static_cast<unsigned>(resourceSet.numberOfResources());
  if (!result)
  {
    std::cerr << "addResource() call failed" << std::endl;
    status += 1;
  }
  else if (n != 2)
  {
    std::cerr << "Wrong number of resources: " << n << ", should be 2" << std::endl;
    status += 1;
  }

  // Add 1st system w/different id and role
  result = resourceSet.addResource(
    system1, "system1-different-id", "", smtk::common::ResourceSet::SCENARIO);
  n = static_cast<unsigned>(resourceSet.numberOfResources());
  if (!result)
  {
    std::cerr << "addResource() call failed" << std::endl;
    status += 1;
  }
  else if (n != 3)
  {
    std::cerr << "Wrong number of resources: " << n << ", should be 3" << std::endl;
    status += 1;
  }

  // Try using same id twice
  result = resourceSet.addResource(system2, "system2");
  n = static_cast<unsigned>(resourceSet.numberOfResources());
  if (result)
  {
    std::cerr << "addResource() call didn't fail" << std::endl;
    status += 1;
  }
  else if (n != 3)
  {
    std::cerr << "Wrong number of resources: " << n << ", should be 3" << std::endl;
    status += 1;
  }

  // Check resource ids
  std::vector<std::string> ids = resourceSet.resourceIds();
  if (ids.size() != 3)
  {
    std::cerr << "Wrong number of ids: " << ids.size() << ", should be 3" << std::endl;
    status += 1;
  }
  else
  {
    const char* expectedNames[] = { "system1", "system2", "system1-different-id" };
    for (unsigned i = 0; i < ids.size(); i++)
    {
      if (ids[i] != expectedNames[i])
      {
        std::cerr << "Wrong resource name " << ids[i] << ", should be " << expectedNames[i]
                  << std::endl;
        status += 1;
      }
    }
  }

  // Check resource info
  smtk::common::Resource::Type rtype;
  smtk::common::ResourceSet::ResourceRole role;
  smtk::common::ResourceSet::ResourceState state;
  std::string link;
  result = resourceSet.resourceInfo("system2", rtype, role, state, link);
  if (!result)
  {
    std::cerr << "info() call failed" << std::endl;
    status += 1;
  }
  else
  {
    if (rtype != smtk::common::Resource::ATTRIBUTE)
    {
      std::cerr << "Incorrect resource type " << rtype << ", should be "
                << smtk::common::Resource::ATTRIBUTE << std::endl;
      status += 1;
    }
    if (role != smtk::common::ResourceSet::INSTANCE)
    {
      std::cerr << "Incorrect resource role " << role << ", should be "
                << smtk::common::ResourceSet::INSTANCE << std::endl;
      status += 1;
    }
    if (state != smtk::common::ResourceSet::LOADED)
    {
      std::cerr << "Incorrect resource state " << state << ", should be "
                << smtk::common::ResourceSet::LOADED << std::endl;
      status += 1;
    }
    if (link != "path2")
    {
      std::cerr << "Incorrect resource link \"" << link << "\", should be \"path2\"" << std::endl;
      status += 1;
    }
  }

  // Retrieve resource
  smtk::common::ResourcePtr resource;
  result = resourceSet.get("system2", resource);
  if (!result)
  {
    std::cerr << "get() failed" << std::endl;
    status += 1;
  }
  rtype = resource->resourceType();
  if (rtype != smtk::common::Resource::ATTRIBUTE)
  {
    std::cerr << "Incorrect resource type " << rtype << ", should be "
              << smtk::common::Resource::ATTRIBUTE << std::endl;
    status += 1;
  }

  std::cout << "Number of errors: " << status << std::endl;
  return status;
}
