/*
 * This file is part of VoidArchiveTool.
 *
 * Copyright (C) 2025 Yanczi
 *
 * Void Archive Toolis free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

#pragma once

#include <iostream>
#include <cstdint>
#include <filesystem>
#include <algorithm>
#include <vector>
#include <fstream>
#include <stdexcept>
#include <utility>
#include <memory>
#include <string>
#include <xxhash.h>
#include <nlohmann/json.hpp>

#include "DataStruct.h"
#include "ChunkManager.h"
#include "EncryptionManager.h"


#define KEY_ZIP             "compress"      // Pliki do skompresowania
#define KEY_RAW             "raw"           // Pliki które mają pozostać w oryginalnej formie
#define KEY_IGNORE          "ignore"        // Pliki pominięte przy pakowaniu
#define KEY_ENCRYPT         "encrypt"       // Plili które mają być zaszyfrowane

#define ALL_FILE            ".*"            // Wszystkie pliki

struct PathConf
{
	std::string path;
	int16_t parameter;
};

class CreateCargo {
public:
	CreateCargo();
	virtual ~CreateCargo();

	// Punk wejścia do tworzenia archivum
	bool Create(const std::string&, const int16_t&);

private:
	const std::string signature;
	const std::string extension;
	const short version;

	short methodFlags;


	std::string catalogPath;
	std::string tempFile;
	std::string cargoFile;

	std::vector<std::string> filesList;

	EncryptionManager crypt;
	bool hppKey;

	// listy wyjątków
	std::vector<std::string> ignoreList;
	std::vector<std::string> zipList;
	std::vector<std::string> encList;

	// Główna lista plików z parametrami
	std::vector<PathConf> filesPaths;


	std::ofstream cargo;
	uint64_t offset;



	// Tworzenie listy plików do spakowania
	bool GetFileList(const std::string&);

	// Konwersja ścieżki na unix like
	std::string PathToUnixLike(std::string);

	// Kasowanie wskazanego katalogu ze ścieżki
	std::string RemoveStartPath(const std::filesystem::path&);

	// Trworzenie archiwum
	bool WriteCargo();

	// Tworzenie nagłowka pliku
	CargoHead CreateCargoHead(const uint32_t&, const uint64_t&);

	// Przygotowanie nagłówków i plików
	std::vector<FilesTable> ComputingHeadFiles();

	// Wczytanie filtrów wyjątków
	void GetFilters(const std::string&);

	// Sprawdza czy plik znajduje się na liście
	void computingBytes(const int16_t&, std::vector<char>&, std::vector<char>&);

	// Sprawdzanie rozszeżeń plików
	bool CheckFileExtension(const std::string&, const std::vector<std::string>&);

	// Zamień cały ciąg na duże litery
	std::string UpperString(std::string);

	// Wygenerój FNV-1a HASH
	uint64_t fnv64(const std::string& data);

	// Znajdź wskazany element na liście
	bool FindOnTheList(const std::vector<std::string>&, const std::string&);
};

