#include <iostream>
#include "win.h"
#include "buffer.h"
#include "cryptography.h"
#include "func.h"
#include "arg_func.h"

#ifdef _DEBUG

int main()
{
	const char* label = "facebook";
	Arg args = Arg::Print_all_p;
	if (args == Arg::Error) return 1;

	Buffer encrypted_buffer;
	if (!encrypted_buffer.load_from_file("passwords.bin"))
		if (!(args == Arg::Generate || args == Arg::Input)) {
			printf_s("No passwords, try generating password\n");
			return 1;
		}

	std::string user_pass = "123";
	Cryptography crypto(user_pass.c_str(), user_pass.size());
	Buffer decrypted_buffer;
	if (encrypted_buffer.size > 0)
		if (!crypto.decrypt(&encrypted_buffer, &decrypted_buffer)) return 1;

	if (decrypted_buffer.taken < 8) {
		Index index = { 0, 0 };
		index.offset = sizeof(Index);
		decrypted_buffer.add_end((uint8_t*)&index, sizeof(Index));
	}

	std::optional<LoginInfoPointer> login_info;

	switch (args)
	{
	case Arg::Get:
		login_info = arg_get(decrypted_buffer, label);
		break;

	case Arg::Generate:
		login_info = arg_new_password(decrypted_buffer, encrypted_buffer, label, crypto, true);
		break;

	case Arg::List:
		arg_list(decrypted_buffer);
		break;

	case Arg::Delete:
		arg_delete(decrypted_buffer, encrypted_buffer, label, crypto);
		break;

	case Arg::Print_all_p:
		arg_print_all_p(decrypted_buffer, user_pass);
		break;

	case Arg::Input:
		login_info = arg_new_password(decrypted_buffer, encrypted_buffer, label, crypto, false);
		break;

	case Arg::Username:
		arg_username(decrypted_buffer, encrypted_buffer, label, crypto);
		break;

	case Arg::Name:
		arg_label_name(decrypted_buffer, encrypted_buffer, label, crypto);
		break;

	case Arg::Change:
		arg_change(decrypted_buffer, encrypted_buffer, user_pass, crypto);
		break;

	case Arg::Show:
		arg_show(decrypted_buffer, label);
		break;
	}

	if (!login_info.has_value()) return 0;

	printf_s("Username: %s\n", login_info.value().username);
	printf_s("Password: %s\n", login_info.value().password);
}

#else

int main(int argc, char** argv)
{
	char* label = nullptr;
	Arg args = get_args(argc, argv, &label);
	if (args == Arg::Error) return 1;

	Buffer encrypted_buffer;
	if (!encrypted_buffer.load_from_file("passwords.bin"))
		if (!(args == Arg::Generate || args == Arg::Input)) {
			printf_s("No passwords, try generating password\n");
			return 1;
		}

	printf_s("Input main password:");
	std::string user_pass = get_user_password();
	if (user_pass.empty())
	{
		printf_s("Error getting password\n");
		return 1;
	}

	Cryptography crypto(user_pass.c_str(), user_pass.size());

	Buffer decrypted_buffer;
	if (encrypted_buffer.size > 0)
		if (!crypto.decrypt(&encrypted_buffer, &decrypted_buffer)) return 1;

	if (decrypted_buffer.taken < 8) {
		Index index = { 0, 0 };
		index.offset = sizeof(Index);
		decrypted_buffer.add_end((uint8_t*)&index, sizeof(Index));
	}

	std::optional<LoginInfoPointer> login_info;

	switch (args)
	{
	case Arg::Get:
		login_info = arg_get(decrypted_buffer, label);
		break;

	case Arg::Generate:
		login_info = arg_new_password(decrypted_buffer, encrypted_buffer, label, crypto, true);
		break;

	case Arg::List:
		arg_list(decrypted_buffer);
		break;

	case Arg::Delete:
		arg_delete(decrypted_buffer, encrypted_buffer, label, crypto);
		break;

	case Arg::Print_all_p:
		arg_print_all_p(decrypted_buffer, user_pass);
		break;

	case Arg::Input:
		login_info = arg_new_password(decrypted_buffer, encrypted_buffer, label, crypto, false);
		break;

	case Arg::Username:
		arg_username(decrypted_buffer, encrypted_buffer, label, crypto);
		break;

	case Arg::Name:
		arg_label_name(decrypted_buffer, encrypted_buffer, label, crypto);
		break;

	case Arg::Change:
		arg_change(decrypted_buffer, encrypted_buffer, user_pass, crypto);
		break;

	case Arg::Show:
		arg_show(decrypted_buffer, label);
		break;
	}

	if (!login_info.has_value()) return 1;

	printf_s("Username: %s\n", login_info.value().username);
	put_data_on_clipboard(login_info.value().password);
	printf_s("Password copied to clipboard\n");

}

#endif // _DEBUG