// Copyright (c) 2023 Codemongous LLC. All Rights Reserved.

#pragma once

#include <cstdint>
#include <memory>
#include <string>
#include <vector>

using std::shared_ptr;
using std::vector;
using std::wstring;

namespace Sourcify
{
	class ISCW_UScriptStruct;
	enum class SourcifyCoreSettingsEmittedCodeIndentType : uint8_t
	{
		Tab,
		Spaces
	};

	enum class SourcifyCoreSettingsToolTipCommentStyle : uint8_t
	{
		DoNotComment,
		CommentWithSlashes,
		CommentWithSlashesAndStars,
		CommentWithSlashesAndStarsMultiline
	};

	struct ISourcifyCoreSettings
	{
	public:
		virtual ~ISourcifyCoreSettings() {}

		virtual bool GetDeclareDelegatesInsideClass() const = 0;
		virtual SourcifyCoreSettingsEmittedCodeIndentType GetIndentType() const = 0;
		virtual int32_t GetNumIndentSpaces() const = 0;
		virtual int32_t GetNumLinesBetweenTypeDeclarations() const = 0;
		virtual int32_t GetNumLinesBetweenFunctionAndPropertyDeclarationBlocks() const  = 0;
		virtual int32_t GetNumLinesBetweenPropertyDeclarations() const = 0;
		virtual int32_t GetNumLinesBetweenFunctionDeclarations() const = 0;
		virtual int32_t GetNumLinesBetweenClassAccessBlocks() const = 0;
		virtual int32_t GetNumSpacesAroundEqualSignInMetaTags() const = 0;
		virtual const vector<wstring>& GetAssetPrefixesToIgnore() const = 0;
		virtual bool GetEnsurePropertiesHaveDefaultValues() const = 0;
		virtual SourcifyCoreSettingsToolTipCommentStyle GetToolTipCommentStyle() const = 0;
		virtual const wstring& GetCurrentSourcifyMetaTag() const = 0;
		virtual const vector<wstring>& GetPreviousSourcifyMetaTags() const = 0;
		virtual const wstring& GetDefaultCodeExportPath() const = 0;
		
		/**
		 * Gets the default hardcoded list of UStruct types to initialize members.
		 * This list contains built-in UE types that can be safely initialized as member fields.
		 * @return Const reference to the immutable list of struct types to initialize
		 */
		virtual const vector<shared_ptr<ISCW_UScriptStruct>>& GetDefaultStructTypesToInitialize() const = 0;
		
		/**
		 * Gets the user-configurable list of additional UStruct types to initialize members.
		 * This allows users to extend the default initialization list with project-specific types.
		 * @return Const reference to the user-configured list of struct types to initialize
		 */
		virtual const vector<shared_ptr<ISCW_UScriptStruct>>& GetUserStructTypesToInitialize() const = 0;
		
		virtual void SetDeclareDelegatesInsideClass(const bool InDeclareDelegatesInsideClass) = 0;
		virtual void SetIndentType(const SourcifyCoreSettingsEmittedCodeIndentType InSpaceType) = 0;
		virtual void SetNumIndentSpaces(const int32_t InNumIndentSpaces) = 0;
		virtual void SetNumLinesBetweenTypeDeclarations(const int32_t InNumLinesBetweenTypeDeclarations) = 0;
		virtual void SetNumLinesBetweenFunctionAndPropertyDeclarationBlocks(const int32_t InNumLinesBetweenFunctionAndPropertyDeclarations) = 0;
		virtual void SetNumLinesBetweenPropertyDeclarations(const int32_t InNumLinesBetweenPropertyDeclarations) = 0;
		virtual void SetNumLinesBetweenFunctionDeclarations(const int32_t InNumLinesBetweenFunctionDeclarations) = 0;
		virtual void SetNumLinesBetweenClassAccessBlocks(const int32_t InNumLinesBetweenClassAccessBlocks) = 0;
		virtual void SetNumSpacesAroundEqualSignInMetaTags(const int32_t InNumSpacesAroundEqualSignInMetaTags) = 0;
		virtual void SetAssetPrefixesToIgnore(const vector<wstring>& InAssetPrefixesToIgnore) = 0;
		virtual void SetEnsurePropertiesHaveDefaultValues(const bool InEnsurePropertiesHaveDefaultValues) = 0;
		virtual void SetToolTipCommentStyle(SourcifyCoreSettingsToolTipCommentStyle InToolTipCommentStyle) = 0;
		virtual void SetCurrentSourcifyMetaTag(const wstring& InCurrentSourcifyMetaTag) = 0;
		virtual void SetPreviousSourcifyMetaTags(const vector<wstring>& InPreviousSourcifyMetaTags) = 0;
		virtual void SetDefaultCodeExportPath(const wstring& InDefaultCodeExportPath) = 0;
		virtual void SetDefaultStructTypesToInitialize(const vector<shared_ptr<ISCW_UScriptStruct>>& structs) = 0;
		virtual void SetUserStructTypesToInitialize(const vector<shared_ptr<ISCW_UScriptStruct>>& structs) = 0;
		virtual bool GetGenerateProjectFiles() const = 0;
		virtual void SetGenerateProjectFiles(const bool InGenerateProjectFiles) = 0;

#if SOURCIFY_DEBUG
		virtual bool GetCompileAfterGeneratingCode() const = 0;
		virtual void SetCompileAfterGeneratingCode(const bool InCompileAfterGeneratingCode) = 0;
		virtual bool GetReloadAfterGeneratingCode() const = 0; 
		virtual void SetReloadAfterGeneratingCode(const bool InReloadAfterGeneratingCode) = 0;
#endif
	protected:
		ISourcifyCoreSettings() {}
	};
}