/*
        Copyright 2013 to 2017 TeamWin
        This file is part of TWRP/TeamWin Recovery Project.

        TWRP is free software: you can redistribute it and/or modify
        it under the terms of the GNU General Public License as published by
        the Free Software Foundation, either version 3 of the License, or
        (at your option) any later version.

        TWRP 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 General Public License for more details.

        You should have received a copy of the GNU General Public License
        along with TWRP.  If not, see <http://www.gnu.org/licenses/>.
*/

#define __STDC_FORMAT_MACROS 1
#include <string>
#include <sys/wait.h>
#include <sys/stat.h>
#include <pthread.h>
#include <zlib.h>
#include <inttypes.h>
#include "twrpAdbBuFifo.hpp"
#include "twcommon.h"
#include "data.hpp"
#include "variables.h"
#include "partitions.hpp"
#include "twrp-functions.hpp"
#include "gui/gui.hpp"
#include "gui/objects.hpp"
#include "gui/pages.hpp"
#include "adbbu/twadbstream.h"
#include "adbbu/libtwadbbu.hpp"

twrpAdbBuFifo::twrpAdbBuFifo(void) {
	unlink(TW_ADB_FIFO);
}

void twrpAdbBuFifo::Check_Adb_Fifo_For_Events(void) {
	char cmd[512];
	int ret;

	memset(&cmd, 0, sizeof(cmd));

	if (read(adb_fifo_fd, &cmd, sizeof(cmd)) > 0) {
		LOGINFO("adb backup cmd: %s\n", cmd);
		std::string cmdcheck(cmd);
		cmdcheck = cmdcheck.substr(0, strlen(ADB_BACKUP_OP));
		std::string Options(cmd);
		Options = Options.substr(strlen(ADB_BACKUP_OP) + 1, strlen(cmd));
		if (cmdcheck == ADB_BACKUP_OP)
			Backup_ADB_Command(Options);
		else {
			Restore_ADB_Backup();
		}
	}
}

bool twrpAdbBuFifo::start(void) {
	LOGINFO("Starting Adb Backup FIFO\n");
	unlink(TW_ADB_FIFO);
	if (mkfifo(TW_ADB_FIFO, 06660) != 0) {
		LOGINFO("Unable to mkfifo %s\n", TW_ADB_FIFO);
		return false;
	}
	adb_fifo_fd = open(TW_ADB_FIFO, O_RDONLY | O_NONBLOCK);
	if (adb_fifo_fd < 0) {
		LOGERR("Unable to open TW_ADB_FIFO for reading.\n");
		close(adb_fifo_fd);
		return false;
	}
	while (true) {
		Check_Adb_Fifo_For_Events();
		usleep(8000);
	}
	//Shouldn't get here but cleanup anwyay
	close(adb_fifo_fd);
	return true;
}

pthread_t twrpAdbBuFifo::threadAdbBuFifo(void) {
	pthread_t thread;
	ThreadPtr adbfifo = &twrpAdbBuFifo::start;
	PThreadPtr p = *(PThreadPtr*)&adbfifo;
	pthread_create(&thread, NULL, p, this);
	return thread;
}

bool twrpAdbBuFifo::Backup_ADB_Command(std::string Options) {
	std::vector<std::string> args;
	std::string Backup_List;
	bool adbbackup = true, ret = false;
	std::string rmopt = "--";

	std::replace(Options.begin(), Options.end(), ':', ' ');
	args = TWFunc::Split_String(Options, " ");

	DataManager::SetValue(TW_USE_COMPRESSION_VAR, 0);
	DataManager::SetValue(TW_SKIP_DIGEST_GENERATE_VAR, 0);

	if (args[1].compare("--twrp") != 0) {
		gui_err("twrp_adbbu_option=--twrp option is required to enable twrp adb backup");
		if (!twadbbu::Write_TWERROR())
			LOGERR("Unable to write to ADB Backup\n");
		sleep(2);
		return false;
	}

	for (unsigned i = 2; i < args.size(); i++) {
		int compress;

		std::string::size_type size = args[i].find(rmopt);
		if (size != std::string::npos)
			args[i].erase(size, rmopt.length());

		if (args[i].compare("compress") == 0) {
			gui_msg("compression_on=Compression is on");
			DataManager::SetValue(TW_USE_COMPRESSION_VAR, 1);
			continue;
		}
		DataManager::GetValue(TW_USE_COMPRESSION_VAR, compress);
		gui_print("%s\n", args[i].c_str());
		std::string path;
		path = "/" + args[i];
		TWPartition* part = PartitionManager.Find_Partition_By_Path(path);
		if (part) {
			Backup_List += path;
			Backup_List += ";";
		}
		else {
			gui_msg(Msg(msg::kError, "partition_not_found=path: {1} not found in partition list")(path));
			if (!twadbbu::Write_TWERROR())
				LOGERR("Unable to write to TWRP ADB Backup.\n");
		return false;
	}
}

	if (Backup_List.empty()) {
		DataManager::GetValue("tw_backup_list", Backup_List);
		if (Backup_List.empty()) {
			gui_err("no_partition_selected=No partitions selected for backup.");
			return false;
		}
	}
	else
		DataManager::SetValue("tw_backup_list", Backup_List);

	DataManager::SetValue("tw_action", "clear");
	DataManager::SetValue("tw_action_text1", gui_lookup("running_recovery_commands", "Running Recovery Commands"));
	DataManager::SetValue("tw_action_text2", "");
	gui_changePage("action_page");

	ret = PartitionManager.Run_Backup(adbbackup);
	DataManager::SetValue(TW_BACKUP_NAME, gui_lookup("auto_generate", "(Auto Generate)"));
	if (!ret) {
		gui_err("backup_fail=Backup failed");
		return false;
	}
	gui_msg("backup_complete=Backup Complete");
	DataManager::SetValue("ui_progress", 100);
	sleep(2); //give time for user to see messages on console
	gui_changePage("main");
	return true;
}

bool twrpAdbBuFifo::Restore_ADB_Backup(void) {
	int partition_count = 0;
	std::string Restore_Name;
	std::size_t pos = 0;
	struct AdbBackupFileTrailer adbmd5;
	struct PartitionSettings part_settings;
	int adb_control_twrp_fd, adb_write_fd, systemro;
	int adb_control_bu_fd, ret = 0;
	char cmd[512];

	part_settings.total_restore_size = 0;

	PartitionManager.Mount_All_Storage();
	DataManager::SetValue(TW_SKIP_DIGEST_CHECK_VAR, 0);
	LOGINFO("opening TW_ADB_BU_CONTROL\n");
	adb_control_bu_fd = open(TW_ADB_BU_CONTROL, O_WRONLY | O_NONBLOCK);
	LOGINFO("opening TW_ADB_TWRP_CONTROL\n");
	adb_control_twrp_fd = open(TW_ADB_TWRP_CONTROL, O_RDONLY | O_NONBLOCK);
	memset(&adbmd5, 0, sizeof(adbmd5));

	DataManager::SetValue("tw_action", "clear");
	DataManager::SetValue("tw_action_text1", gui_lookup("running_recovery_commands", "Running Recovery Commands"));
	DataManager::SetValue("tw_action_text2", "");
	gui_changePage("action_page");

	while (true) {
		memset(&cmd, 0, sizeof(cmd));
		if (read(adb_control_twrp_fd, cmd, sizeof(cmd)) > 0) {
			struct AdbBackupControlType cmdstruct;

			memset(&cmdstruct, 0, sizeof(cmdstruct));
			memcpy(&cmdstruct, cmd, sizeof(cmdstruct));
			std::string cmdtype = cmdstruct.get_type();
			if (cmdtype == TWSTREAMHDR) {
				struct AdbBackupStreamHeader twhdr;
				memcpy(&twhdr, cmd, sizeof(cmd));
				LOGINFO("ADB Partition count: %" PRIu64 "\n", twhdr.partition_count);
				LOGINFO("ADB version: %" PRIu64 "\n", twhdr.version);
				if (twhdr.version != ADB_BACKUP_VERSION) {
					LOGERR("Incompatible adb backup version!\n");
					ret = false;
					break;
				}
				partition_count = twhdr.partition_count;
			}
			else if (cmdtype == MD5TRAILER) {
				LOGINFO("Reading ADB Backup MD5TRAILER\n");
				memcpy(&adbmd5, cmd, sizeof(cmd));
			}
			else if (cmdtype == TWMD5) {
				int check_digest;

				DataManager::GetValue(TW_SKIP_DIGEST_CHECK_VAR, check_digest);
				if (check_digest > 0) {
					TWFunc::GUI_Operation_Text(TW_VERIFY_DIGEST_TEXT, gui_parse_text("{@verifying_digest}"));
					gui_msg("verifying_digest=Verifying Digest");
					struct AdbBackupFileTrailer md5check;
					LOGINFO("Verifying md5sums\n");

					memset(&md5check, 0, sizeof(md5check));
					memcpy(&md5check, cmd, sizeof(cmd));
					if (strcmp(md5check.md5, adbmd5.md5) != 0) {
						LOGERR("md5 doesn't match!\n");
						LOGERR("Stored file md5: %s\n", adbmd5.md5);
						LOGERR("ADB Backup check md5: %s\n", md5check.md5);
						ret = false;
						break;
					}
					else {
						LOGINFO("ADB Backup md5 matches\n");
						LOGINFO("Stored file md5: %s\n", adbmd5.md5);
						LOGINFO("ADB Backup check md5: %s\n", md5check.md5);
						continue;
					}
				} else {
					gui_msg("skip_digest=Skipping Digest check based on user setting.");
					continue;
				}

			}
			else if (cmdtype == TWENDADB) {
				LOGINFO("received TWENDADB\n");
				ret = 1;
				break;
			}
			else {
				struct twfilehdr twimghdr;
				memcpy(&twimghdr, cmd, sizeof(cmd));
				std::string cmdstr(twimghdr.type);
				Restore_Name = twimghdr.name;
				part_settings.total_restore_size = twimghdr.size;
				if (cmdtype == TWIMG) {
					LOGINFO("ADB Type: %s\n", twimghdr.type);
					LOGINFO("ADB Restore_Name: %s\n", Restore_Name.c_str());
					LOGINFO("ADB Restore_size: %" PRIu64 "\n", part_settings.total_restore_size);
					string compression = (twimghdr.compressed == 1) ? "compressed" : "uncompressed";
					LOGINFO("ADB compression: %s\n", compression.c_str());
					std::string Backup_FileName;
					std::size_t pos = Restore_Name.find_last_of("/");
					std::string path = "/" + Restore_Name.substr(pos, Restore_Name.size());
					pos = path.find_first_of(".");
					path = path.substr(0, pos);
					if (path.substr(0,1).compare("//")) {
						path = path.substr(1, path.size());
					}

					pos = Restore_Name.find_last_of("/");
					Backup_FileName = Restore_Name.substr(pos + 1, Restore_Name.size());
					part_settings.Part = PartitionManager.Find_Partition_By_Path(path);
					part_settings.Backup_Folder = path;
					PartitionManager.Set_Restore_Files(path);
					part_settings.partition_count = partition_count;
					part_settings.adbbackup = true;
					part_settings.adb_compression = twimghdr.compressed;
					part_settings.PM_Method = PM_RESTORE;
					ProgressTracking progress(part_settings.total_restore_size);
					part_settings.progress = &progress;
					if (!PartitionManager.Restore_Partition(&part_settings)) {
						LOGERR("ADB Restore failed.\n");
						ret = false;
						break;
					}
				}
				else if (cmdtype == TWFN) {
					LOGINFO("ADB Type: %s\n", twimghdr.type);
					LOGINFO("ADB Restore_Name: %s\n", Restore_Name.c_str());
					LOGINFO("ADB Restore_size: %" PRIi64 "\n", part_settings.total_restore_size);
					string compression = (twimghdr.compressed == 1) ? "compressed" : "uncompressed";
					LOGINFO("ADB compression: %s\n", compression.c_str());
					std::string Backup_FileName;
					std::size_t pos = Restore_Name.find_last_of("/");
					std::string path = "/" + Restore_Name.substr(pos, Restore_Name.size());
					pos = path.find_first_of(".");
					path = path.substr(0, pos);
					if (path.substr(0,1).compare("//")) {
						path = path.substr(1, path.size());
					}

					pos = Restore_Name.find_last_of("/");
					Backup_FileName = Restore_Name.substr(pos + 1, Restore_Name.size());
					pos = Restore_Name.find_last_of("/");
					part_settings.Part = PartitionManager.Find_Partition_By_Path(path);
					part_settings.Part->Set_Backup_FileName(Backup_FileName);
					PartitionManager.Set_Restore_Files(path);

					if (path.compare("/system") == 0) {
						if (part_settings.Part->Is_Read_Only()) {
							if (!twadbbu::Write_TWERROR())
								LOGERR("Unable to write to TWRP ADB Backup.\n");
							gui_msg(Msg(msg::kError, "restore_read_only=Cannot restore {1} -- mounted read only.")(part_settings.Part->Backup_Display_Name));
							ret = false;
							break;

						}
					}
					part_settings.partition_count = partition_count;
					part_settings.adbbackup = true;
					part_settings.adb_compression = twimghdr.compressed;
					part_settings.total_restore_size += part_settings.Part->Get_Restore_Size(&part_settings);
					part_settings.PM_Method = PM_RESTORE;
					ProgressTracking progress(part_settings.total_restore_size);
					part_settings.progress = &progress;
					if (!PartitionManager.Restore_Partition(&part_settings)) {
						LOGERR("ADB Restore failed.\n");
						ret = false;
						break;
					}
				}
			}
		}
	}

	if (ret != false)
		gui_msg("restore_complete=Restore Complete");
	else
		gui_err("restore_error=Error during restore process.");

	if (!twadbbu::Write_TWENDADB())
		ret = false;
	sleep(2); //give time for user to see messages on console
	DataManager::SetValue("ui_progress", 100);
	gui_changePage("main");
	close(adb_control_bu_fd);
	return ret;
}
