/*
 * swmod_opkg.c: SWMOD deamon
 *
 * Copyright (C) 2020-2023 IOPSYS Software Solutions AB. All rights reserved.
 *
 * Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
 *
 * See LICENSE file for license related information.
 */

#include "tools.h"
#include "swmod.h"
#include "swmod_uci.h"
#include "swmod_opkg.h"
#include "swmod_common.h"
#include "opkg_utils.h"
#include "swmod_api.h"

static bool validate_args(const char *url, char *output, int out_len)
{
	if (output == NULL || out_len <= 0) {
		return false;
	}

	if (url == NULL) {
		snprintf(output, out_len, "Package path not given");
		return false;
	}

	if (url[0] == '\0') {
		snprintf(output, out_len, "Package path not given");
		return false;
	}

	return true;
}

int swmod_perform_installation(const char *url, const char *uname, const char *pwd, char *output, int out_len)
{
	int err = -1;
	char package_path[2049] = {0};

	if (validate_args(url, output, out_len) == false)
		return err;

	if (strstr(url, "file://") != NULL) {
		/* This is a local file */
		snprintf(package_path, sizeof(package_path), "%s", url+6);
	} else {
		unsigned long size = get_remote_file_size(url, uname, pwd);
		if (size == 0) {
			snprintf(output, out_len, "Failed to read package info or package is empty");
			return err;
		}

		if (!memory_available(size, DW_TMP_DIR_PATH)) {
			snprintf(output, out_len, "No enough space in system to download the package");
			return err;
		}

		/* This is a remote package, need to download first */
		if(0 != download_remote_package(url, uname, pwd, DW_PKG_LOCAL_PATH)) {
			snprintf(output, out_len, "Package download failed from %s", url);
			goto end;
		}

		snprintf(package_path, sizeof(package_path), "%s", DW_PKG_LOCAL_PATH);
	}

	if (strlen(package_path) == 0) {
		snprintf(output, out_len, "Invalid package name");
		goto end;
	}

	err = opkg_install_pkg(package_path, output, out_len);
	if (0 != err) {
		snprintf(output, out_len, "Internal Error");
	}

end:
	/* Remove the downloaded package if it is in local dir of host or container */
	if (file_exists(DW_PKG_LOCAL_PATH)) {
		remove(DW_PKG_LOCAL_PATH);
	}

	return err;
}

int swmod_perform_upgrade(const char *url, const char *uname, const char *pwd, char *output, int out_len)
{
	int err = -1;
	char package_path[2049] = {0};

	if (validate_args(url, output, out_len) == false)
		return err;

	if (strchr(url, ':') != NULL) {
		/* This is a remote package, need to download first */
		if(0 != download_remote_package(url, uname, pwd, DW_PKG_LOCAL_PATH)) {
			snprintf(output, out_len, "Package download failed from %s", url);
			return err;
		}

		snprintf(package_path, sizeof(package_path), "%s", DW_PKG_LOCAL_PATH);
	} else {
		snprintf(package_path, sizeof(package_path), "%s", url);
	}

	err = opkg_update_pkg(package_path, output, out_len);
	if (0 != err) {
		snprintf(output, out_len, "Internal Error");
	}

	/* Remove the downloaded package if it is in local dir of host or container */
	if (file_exists(DW_PKG_LOCAL_PATH)) {
		remove(DW_PKG_LOCAL_PATH);
	}

	return err;
}

int swmod_perform_uninstall(const char *pname, char *output, int outlen)
{
	int err = -1;

	if (validate_args(pname, output, outlen) == false)
		return err;

	char version[MAX_LEN_64] = {0};
	char line[MAX_LEN_512] = {0};
	opkg_get_version(pname, version, sizeof(version));
	snprintf(line, sizeof(line), "\nPackage Name:%s Version:%s\n", pname, version);

	err = opkg_remove_pkg(pname, output, outlen);
	if (0 != err) {
		snprintf(output, outlen, "Internal Error");
	}

	int line_len = strlen(line);
	if (strlen(output) + line_len < outlen) {
		strncat(output, line, line_len);
	}

	return err;
}
