/*
        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);
}

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

	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)
			return Backup_ADB_Command(Options);
		else {
			return Restore_ADB_Backup();
		}
	}

	return true;
}

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");
		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));
			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 (1) {
		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 cmdstr(cmdstruct.type);
			std::string cmdtype = cmdstr.substr(0, sizeof(cmdstruct.type) - 1);
			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");
					break;
				}
				partition_count = twhdr.partition_count;
			}
			else if (cmdtype == MD5TRAILER) {
				LOGINFO("Restoring MD5TRAILER\n");
				memcpy(&adbmd5, cmd, sizeof(cmd));
			}
			else if (cmdtype == TWMD5) {
				struct AdbBackupFileTrailer md5check;
				LOGINFO("Restoring TWMD5\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("file md5: %s\n", adbmd5.md5);
					LOGERR("check md5: %s\n", md5check.md5);
					ret = false;
					break;
				}
				else {
					LOGINFO("adbrestore md5 matches\n");
					LOGINFO("adbmd5.md5: %s\n", adbmd5.md5);
					LOGINFO("md5check.md5: %s\n", md5check.md5);
				}
			}
			else if (cmdtype == TWENDADB) {
				LOGINFO("received TWENDADB\n");
				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");
						return false;
					}
				}
				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()) {
							struct AdbBackupControlType twerror;
							strncpy(twerror.start_of_header, TWRP, sizeof(twerror.start_of_header));
							strncpy(twerror.type, TWERROR, sizeof(twerror.type));
							memset(twerror.space, 0, sizeof(twerror.space));
							twerror.crc = crc32(0L, Z_NULL, 0);
							twerror.crc = crc32(twerror.crc, (const unsigned char*) &twerror, sizeof(twerror));
							if (write(adb_control_bu_fd, &twerror, sizeof(twerror)) < 0) {
								LOGERR("Cannot write to ADB_CONTROL_BU_FD: %s\n", strerror(errno));
							}
							gui_msg(Msg(msg::kError, "restore_read_only=Cannot restore {1} -- mounted read only.")(part_settings.Part->Backup_Display_Name));
							return false;

						}
					}
					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");
						return false;
					}
				}
			}
		}
	}
	gui_msg("restore_complete=Restore Complete");

	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");
	return ret;
}
