/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
#ifndef cmCTestMultiProcessHandler_h
#define cmCTestMultiProcessHandler_h

#include "cmConfigure.h" // IWYU pragma: keep

#include <map>
#include <set>
#include <string>
#include <vector>

#include <stddef.h>

#include "cm_uv.h"

#include "cmCTestResourceAllocator.h"
#include "cmCTestTestHandler.h"
#include "cmUVHandlePtr.h"

class cmCTest;
struct cmCTestBinPackerAllocation;
class cmCTestResourceSpec;
class cmCTestRunTest;

/** \class cmCTestMultiProcessHandler
 * \brief run parallel ctest
 *
 * cmCTestMultiProcessHandler
 */
class cmCTestMultiProcessHandler
{
  friend class TestComparator;
  friend class cmCTestRunTest;

public:
  struct TestSet : public std::set<int>
  {
  };
  struct TestMap : public std::map<int, TestSet>
  {
  };
  struct TestList : public std::vector<int>
  {
  };
  struct PropertiesMap
    : public std::map<int, cmCTestTestHandler::cmCTestTestProperties*>
  {
  };
  struct ResourceAllocation
  {
    std::string Id;
    unsigned int Slots;
  };

  cmCTestMultiProcessHandler();
  virtual ~cmCTestMultiProcessHandler();
  // Set the tests
  void SetTests(TestMap& tests, PropertiesMap& properties);
  // Set the max number of tests that can be run at the same time.
  void SetParallelLevel(size_t);
  void SetTestLoad(unsigned long load);
  virtual void RunTests();
  void PrintOutputAsJson();
  void PrintTestList();
  void PrintLabels();

  void SetPassFailVectors(std::vector<std::string>* passed,
                          std::vector<std::string>* failed)
  {
    this->Passed = passed;
    this->Failed = failed;
  }
  void SetTestResults(std::vector<cmCTestTestHandler::cmCTestTestResult>* r)
  {
    this->TestResults = r;
  }

  void SetCTest(cmCTest* ctest) { this->CTest = ctest; }

  void SetTestHandler(cmCTestTestHandler* handler)
  {
    this->TestHandler = handler;
  }

  cmCTestTestHandler* GetTestHandler() { return this->TestHandler; }

  void SetQuiet(bool b) { this->Quiet = b; }

  void InitResourceAllocator(const cmCTestResourceSpec& spec)
  {
    this->ResourceAllocator.InitializeFromResourceSpec(spec);
  }

  void CheckResourcesAvailable();

protected:
  // Start the next test or tests as many as are allowed by
  // ParallelLevel
  void StartNextTests();
  bool StartTestProcess(int test);
  bool StartTest(int test);
  // Mark the checkpoint for the given test
  void WriteCheckpoint(int index);

  void UpdateCostData();
  void ReadCostData();
  // Return index of a test based on its name
  int SearchByName(std::string const& name);

  void CreateTestCostList();

  void GetAllTestDependencies(int test, TestList& dependencies);
  void CreateSerialTestCostList();

  void CreateParallelTestCostList();

  // Removes the checkpoint file
  void MarkFinished();
  void EraseTest(int index);
  void FinishTestProcess(cmCTestRunTest* runner, bool started);

  static void OnTestLoadRetryCB(uv_timer_t* timer);

  void RemoveTest(int index);
  // Check if we need to resume an interrupted test set
  void CheckResume();
  // Check if there are any circular dependencies
  bool CheckCycles();
  int FindMaxIndex();
  inline size_t GetProcessorsUsed(int index);
  std::string GetName(int index);

  bool CheckStopTimePassed();
  void SetStopTimePassed();

  void LockResources(int index);
  void UnlockResources(int index);

  bool AllocateResources(int index);
  bool TryAllocateResources(
    int index,
    std::map<std::string, std::vector<cmCTestBinPackerAllocation>>&
      allocations);
  void DeallocateResources(int index);
  bool AllResourcesAvailable();

  // map from test number to set of depend tests
  TestMap Tests;
  TestList SortedTests;
  // Total number of tests we'll be running
  size_t Total;
  // Number of tests that are complete
  size_t Completed;
  size_t RunningCount;
  std::set<size_t> ProcessorsAvailable;
  size_t HaveAffinity;
  bool StopTimePassed = false;
  // list of test properties (indices concurrent to the test map)
  PropertiesMap Properties;
  std::map<int, bool> TestRunningMap;
  std::map<int, bool> TestFinishMap;
  std::map<int, std::string> TestOutput;
  std::vector<std::string>* Passed;
  std::vector<std::string>* Failed;
  std::vector<std::string> LastTestsFailed;
  std::set<std::string> LockedResources;
  std::map<int,
           std::vector<std::map<std::string, std::vector<ResourceAllocation>>>>
    AllocatedResources;
  std::map<int, bool> TestsHaveSufficientResources;
  cmCTestResourceAllocator ResourceAllocator;
  std::vector<cmCTestTestHandler::cmCTestTestResult>* TestResults;
  size_t ParallelLevel; // max number of process that can be run at once
  unsigned long TestLoad;
  unsigned long FakeLoadForTesting;
  uv_loop_t Loop;
  cm::uv_timer_ptr TestLoadRetryTimer;
  cmCTestTestHandler* TestHandler;
  cmCTest* CTest;
  bool HasCycles;
  bool Quiet;
  bool SerialTestRunning;
};

#endif
