#pragma once
#include "common/bitfield.h"
#include "types.h"
#include <functional>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <utility>
#include <vector>
class Error;
namespace Cheats {
enum class CodeType : u8
{
Gameshark,
Count
};
enum class CodeActivation : u8
{
Manual,
EndFrame,
Count,
};
enum class FileFormat : u8
{
Unknown,
DuckStation,
PCSX,
Libretro,
EPSXe,
Count
};
using CodeOption = std::pair<std::string, u32>;
using CodeOptionList = std::vector<CodeOption>;
struct CodeInfo
{
std::string name;
std::string author;
std::string description;
std::string body;
CodeOptionList options;
u16 option_range_start = 0;
u16 option_range_end = 0;
u32 file_offset_start = 0;
u32 file_offset_body_start = 0;
u32 file_offset_end = 0;
CodeType type = CodeType::Gameshark;
CodeActivation activation = CodeActivation::EndFrame;
bool from_database = false;
bool disallow_for_achievements = false;
std::string_view GetNamePart() const;
std::string_view GetNameParentPart() const;
bool HasOptionChoices() const { return (!options.empty()); }
bool HasOptionRange() const { return (option_range_end > option_range_start); }
std::string_view MapOptionValueToName(u32 value) const;
std::string_view MapOptionValueToName(const std::string_view value) const;
u32 MapOptionNameToValue(const std::string_view opt_name) const;
};
using CodeInfoList = std::vector<CodeInfo>;
extern const char* GetTypeName(CodeType type);
extern const char* GetTypeDisplayName(CodeType type);
extern std::optional<CodeType> ParseTypeName(const std::string_view str);
extern const char* GetActivationName(CodeActivation activation);
extern const char* GetActivationDisplayName(CodeActivation activation);
extern std::optional<CodeActivation> ParseActivationName(const std::string_view str);
extern CodeInfoList GetCodeInfoList(const std::string_view serial, std::optional<GameHash> hash, bool cheats,
bool load_from_database, bool sort_by_name);
extern std::vector<std::string_view> GetCodeListUniquePrefixes(const CodeInfoList& list, bool include_empty);
extern const CodeInfo* FindCodeInInfoList(const CodeInfoList& list, const std::string_view name);
extern CodeInfo* FindCodeInInfoList(CodeInfoList& list, const std::string_view name);
extern std::string FormatCodeForFile(const CodeInfo& code);
extern bool ImportCodesFromString(CodeInfoList* dst, const std::string_view file_contents, FileFormat file_format,
bool stop_on_error, Error* error);
extern bool ExportCodesToFile(std::string path, const CodeInfoList& codes, Error* error);
extern bool UpdateCodeInFile(const char* path, const std::string_view name, const CodeInfo* code, Error* error);
extern bool SaveCodesToFile(const char* path, const CodeInfoList& codes, Error* error);
extern void RemoveAllCodes(const std::string_view serial, const std::string_view title, std::optional<GameHash> hash);
extern std::string GetChtFilename(const std::string_view serial, std::optional<GameHash> hash, bool cheats);
extern void ReloadCheats(bool reload_files, bool reload_enabled_list, bool verbose, bool verbose_if_changed,
bool show_disabled_codes);
extern void UnloadAll();
extern bool HasAnySettingOverrides();
extern void ApplySettingOverrides();
extern void ApplyFrameEndCodes();
extern bool AreCheatsEnabled();
extern bool EnumerateManualCodes(std::function<bool(const std::string& name)> callback);
extern bool ApplyManualCode(const std::string_view name);
extern u32 GetActivePatchCount();
extern u32 GetActiveCheatCount();
extern const char* PATCHES_CONFIG_SECTION;
extern const char* CHEATS_CONFIG_SECTION;
extern const char* PATCH_ENABLE_CONFIG_KEY;
}