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

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

	Buffer encrypted_buffer;
	if (!load_buffer_from_file(&encrypted_buffer))
		if (!(args == Args::Generate)) {
			printf_s("No passwords, try generating password\n");
			return 1;
		}

	printf_s("Input main password:");
	std::string user_pass = get_passwd();
	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;

	Pass* pass = nullptr;
	Pass new_pass = { 0 };
	Pass* passwords = nullptr;
	std::string new_string;

	switch (args)
	{
	case Args::Get:

		pass = find_password(&decrypted_buffer, label);
		if (!pass)
		{
			printf_s("Password not found\n");
			return 1;
		}
		break;
	case Args::Generate:

		pass = find_password(&decrypted_buffer, label);

		if (pass != nullptr) generate_password(pass->password);
		else
		{
			generate_password(new_pass.password);
			strcpy_s(new_pass.label, MAX_STRING_SIZE, label);
			decrypted_buffer.add((uint8_t*)&new_pass, sizeof(Pass));
			pass = &new_pass;
		}

		crypto.encrypt(&decrypted_buffer, &encrypted_buffer);
		save_buffer_to_file(&encrypted_buffer);

		break;
	case Args::List:

		passwords = (Pass*)decrypted_buffer.buffer;
		for (int i = 0; i < decrypted_buffer.taken / sizeof(Pass); i++)
		{
			printf_s("%s\n", passwords[i].label);
		}
		return 0;

		break;
	case Args::Delete:
		pass = find_password(&decrypted_buffer, label);

		if (!pass)
		{
			printf_s("Password not found\n");
			return 1;
		}
		else
		{
			decrypted_buffer.remove_fast((uint8_t*)pass, sizeof(Pass));

		}
		crypto.encrypt(&decrypted_buffer, &encrypted_buffer);

		save_buffer_to_file(&encrypted_buffer);

		printf_s("Password deleted\n");

		return 0;
		break;
	case Args::Print_all_p:

		printf_s("input main password for confirmation:\n");
		new_string = get_passwd();
		if (new_string.empty())
		{
			printf_s("Error getting password\n");
			return 1;
		}

		if (new_string != user_pass)
		{
			printf_s("Wrong password\n");
			return 1;
		}

		passwords = (Pass*)decrypted_buffer.buffer;
		for (int i = 0; i < decrypted_buffer.taken / sizeof(Pass); i++)
		{
			printf_s("%s: %s\n", passwords[i].label, passwords[i].password);
		}
		return 0;

		break;

	case Args::Input:
		printf_s("Input password for %s:\n", label);
		new_string = get_passwd();
		if (new_string.empty())
		{
			printf_s("Error getting password\n");
			return 1;
		}

		pass = find_password(&decrypted_buffer, label);

		if (pass != nullptr)
		{
			strcpy_s(pass->password, MAX_STRING_SIZE, new_string.c_str());
		}
		else
		{
			strcpy_s(new_pass.password, MAX_STRING_SIZE, new_string.c_str());
			strcpy_s(new_pass.label, MAX_STRING_SIZE, label);
			decrypted_buffer.add((uint8_t*)&new_pass, sizeof(Pass));
			pass = &new_pass;
		}

		crypto.encrypt(&decrypted_buffer, &encrypted_buffer);
		save_buffer_to_file(&encrypted_buffer);
		break;
	}

	if (pass == nullptr) return 1;
#ifdef _DEBUG
	printf_s("Password: %s", pass->password);
#else
	printf_s("Password copied to clipboard\n");
	put_data_on_clipboard(pass->password);
#endif


}