#pragma once

#include "xtr/core/SelectableSet.h"
#include "xtr/doc/FileVersions.hpp"
#include "xtr/io/CArchiveAdapter.hpp"

namespace xtr::io {

//! Shared CstLoader for rsm and trs
class LegacyCstLoader {
  BOOL needEncoding{ FALSE };
  std::unique_ptr<ccl::semantic::ConceptRecord> cst{ nullptr };
  CArchiveAdapter& ar;

public:
  explicit LegacyCstLoader(CArchiveAdapter& ar) noexcept
    : ar(ar) {}

public:
  void InitOldEncoding() noexcept { needEncoding = TRUE; }

  void LoadBasicProperties(BOOL oldType = FALSE);
  void LoadTerms(BOOL hasTerms, BOOL multipleTerms);
  void LoadInterpretation(BOOL loadWithRef);
  void LoadID();

  [[nodiscard]] const ccl::semantic::ConceptRecord& GetResult() const noexcept { return *cst; }

private:
  [[nodiscard]] static ccl::semantic::CstType LoadV0CstType(int32_t code) noexcept;
};

//! Shared CoreLoader for rsm and trs
class LegacyCoreLoader {
  CArchiveAdapter& ar;

public:
  explicit LegacyCoreLoader(CArchiveAdapter& ar) noexcept
    : ar{ ar } {}

public:
  void DoLoad(ccl::semantic::RSCore& core);

private:
  ccl::lang::ManagedText LoadText();
  ccl::lang::LexicalTerm LoadTerm();
};

//! TRS file legacy loader
class TRSLegacyLoader {
  CArchiveAdapter& ar;
  ccl::semantic::RSForm& schema;

public:
  TRSVersion version{ TRSVersion::old };
  SetOfEntities selection{};
  bool isClaimed{ false };

public:
  explicit TRSLegacyLoader(CArchiveAdapter& ar, ccl::semantic::RSForm& schema) noexcept
    : ar{ ar }, schema{ schema } {}

public:
  void LoadVersion();
  void DoLoad();

private:
  void LoadSecondGen();
  void LoadSchemaProperties(BOOL loadFullName);
  void LoadFirstGen();
  void LoadCst();
  void LoadInheritanceDataFromOldFlag(EntityUID uid, uint16_t loadedStatus);
  void LoadInheritance();
};

} // namespace xtr::io