//=========================================================================
//  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 "cmb/cmbReaderFactory.h"

#include "vtkPVProxyDefinitionIterator.h"
#include "vtkPVXMLElement.h"

#include "vtkSMProxyDefinitionManager.h"
#include "vtkSMProxyManager.h"
#include "vtkSMSession.h"
#include "vtkSMSessionProxyManager.h"

#include "vtkNew.h"
#include "vtkObjectFactory.h"
#include "vtkStringList.h"

class cmbReaderFactory::vtkInternals
{
public:
  vtkInternals() = default;

  // XXX(clang-tidy): Internal class, we don't care about this check.
  // NOLINTNEXTLINE(misc-non-private-member-variables-in-classes)
  bool enablePostProcessing{ false };
};

vtkObjectFactoryNewMacro(cmbReaderFactory);
//----------------------------------------------------------------------------
cmbReaderFactory::cmbReaderFactory()
{
  this->Internals = new vtkInternals();
}

//----------------------------------------------------------------------------
cmbReaderFactory::~cmbReaderFactory()
{
  delete this->Internals;
}
//----------------------------------------------------------------------------
void cmbReaderFactory::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
}
//----------------------------------------------------------------------------
void cmbReaderFactory::SetPostProcessingMode(bool choice)
{
  if (this->Internals->enablePostProcessing != choice)
  {
    this->Internals->enablePostProcessing = choice;
    this->UpdateAvailableReaders();
  }
}
//----------------------------------------------------------------------------
const char* cmbReaderFactory::GetSupportedFileTypes(vtkSMSession* session)
{
  return vtkSMReaderFactory::GetSupportedFileTypes(session);
}
//----------------------------------------------------------------------------
void cmbReaderFactory::UpdateAvailableReaders()
{
  vtkSMReaderFactory::Initialize();

  vtkSMProxyManager* proxyManager = vtkSMProxyManager::GetProxyManager();
  // when we change the server we may not have a session yet. that's ok
  // since we'll come back here after the proxy definitions are loaded
  // from that session.
  if (vtkSMSession* session = proxyManager->GetActiveSession())
  {
    vtkSMSessionProxyManager* sessionProxyManager = session->GetSessionProxyManager();
    vtkSMProxyDefinitionManager* pdm = sessionProxyManager->GetProxyDefinitionManager();

    vtkNew<vtkStringList> groups;
    this->GetGroups(groups);

    for (int i = 0; i < groups->GetNumberOfStrings(); ++i)
    {
      const char* group = groups->GetString(i);
      vtkPVProxyDefinitionIterator* iter = pdm->NewSingleGroupIterator(group);
      for (iter->GoToFirstItem(); !iter->IsDoneWithTraversal(); iter->GoToNextItem())
      {
        vtkPVXMLElement* hints =
          sessionProxyManager->GetProxyHints(iter->GetGroupName(), iter->GetProxyName());
        if (hints && hints->FindNestedElementByName("ReaderFactory"))
        {
          if (
            this->Internals->enablePostProcessing ||
            std::string(iter->GetProxyName()).find("SMTK") != std::string::npos)
          {
            this->RegisterPrototype(iter->GetGroupName(), iter->GetProxyName());
          }
        }
      }
      iter->Delete();
    }
  }
}
