#!/bin/sh
set -o nounset

oneTimeSetUp() {
	# Load the ./play.it library
	. lib/libplayit2.sh
}

setUp() {
	# Set a temporary directory to mess with real files
	TEST_TEMP_DIR=$(mktemp --directory)
	export TEST_TEMP_DIR
}

tearDown() {
	rm --force --recursive "$TEST_TEMP_DIR"
}

test_archive_is_available() {
	local ARCHIVE_BASE_0_PATH

	ARCHIVE_BASE_0_PATH='/some/path/to/archive.tar.gz'
	assertTrue 'archive_is_available "ARCHIVE_BASE_0"'

	unset ARCHIVE_BASE_0_PATH
	assertFalse 'archive_is_available "ARCHIVE_BASE_0"'
}

test_archive_name() {
	local archive_name ARCHIVE_BASE_0_NAME ARCHIVE_BASE_0 PLAYIT_COMPATIBILITY_LEVEL

	ARCHIVE_BASE_0_NAME='setup_sid_meiers_alpha_centauri_2.0.2.23.exe'
	archive_name=$(archive_name 'ARCHIVE_BASE_0')
	assertEquals 'setup_sid_meiers_alpha_centauri_2.0.2.23.exe' "$archive_name"
	unset ARCHIVE_BASE_0_NAME

	# If ARCHIVE_xxx_NAME is not set, the name can be fetched from the legacy variable ARCHIVE_xxx
	PLAYIT_COMPATIBILITY_LEVEL='2.25'
	ARCHIVE_BASE_0='stellaris_3_8_4_1_65337.sh'
	archive_name=$(archive_name 'ARCHIVE_BASE_0')
	assertEquals 'stellaris_3_8_4_1_65337.sh' "$archive_name"
	unset ARCHIVE_BASE_0

	# An error is thrown if no archive name is set
	assertFalse 'archive_name "ARCHIVE_BASE_0"'
}

test_archive_path() {
	local \
		archive_path \
		ARCHIVE_BASE_0_PATH \
		PLAYIT_ARCHIVES_PATH_BASE ARCHIVE_REQUIRED_OPENSSL100_NAME \
		ARCHIVE_INNER PLAYIT_COMPATIBILITY_LEVEL

	ARCHIVE_BASE_0_PATH='/home/jeux/warcraft-3/archives/blizzard/War3-1.27-Installer-enUS-ROC/Installer Tome.mpq'
	archive_path=$(archive_path 'ARCHIVE_BASE_0')
	assertEquals '/home/jeux/warcraft-3/archives/blizzard/War3-1.27-Installer-enUS-ROC/Installer Tome.mpq' "$archive_path"

	# Compute the archive path from its name
	PLAYIT_ARCHIVES_PATH_BASE='/home/jeux/baldurs-gate-2-enhanced-edition/archives/gog.com'
	ARCHIVE_REQUIRED_OPENSSL100_NAME='openssl_1.0.0.tar.xz'
	archive_path=$(archive_path 'ARCHIVE_REQUIRED_OPENSSL100')
	assertEquals '/home/jeux/baldurs-gate-2-enhanced-edition/archives/gog.com/openssl_1.0.0.tar.xz' "$archive_path"
	unset PLAYIT_ARCHIVES_PATH_BASE

	# Get the archive path from the legacy variable ARCHIVE_xxx
	PLAYIT_COMPATIBILITY_LEVEL='2.25'
	ARCHIVE_INNER='/var/tmp/play.it/rayman-origins.A9xV8/gamedata/data1.hdr'
	archive_path=$(archive_path 'ARCHIVE_INNER')
	assertEquals '/var/tmp/play.it/rayman-origins.A9xV8/gamedata/data1.hdr' "$archive_path"
}

test_archive_size() {
	local archive_size ARCHIVE_BASE_0_SIZE

	ARCHIVE_BASE_0_SIZE='42000'
	archive_size=$(archive_size 'ARCHIVE_BASE_0')
	assertEquals '42000' "$archive_size"
	unset ARCHIVE_BASE_0_SIZE

	# Default to 0 if no size is set
	archive_size=$(archive_size 'ARCHIVE_BASE_0')
	assertEquals '0' "$archive_size"
}

test_archive_hash_md5() {
	local archive_hash ARCHIVE_BASE_0_MD5

	ARCHIVE_BASE_0_MD5='6c9bd7e1cf88fdbfa0e75f694bf8b0e5'
	archive_hash=$(archive_hash_md5 'ARCHIVE_BASE_0')
	assertEquals '6c9bd7e1cf88fdbfa0e75f694bf8b0e5' "$archive_hash"
}

test_archive_hash_md5_computed() {
	local archive_hash PLAYIT_WORKDIR ARCHIVE_BASE_0_NAME ARCHIVE_BASE_0_PATH

	PLAYIT_WORKDIR="$TEST_TEMP_DIR"
	mkdir --parents "${PLAYIT_WORKDIR}/cache"
	cat >> "${PLAYIT_WORKDIR}/cache/hashes" <<- EOF
	ARCHIVE_BASE_0 | 6c9bd7e1cf88fdbfa0e75f694bf8b0e5
	EOF
	archive_hash=$(archive_hash_md5_computed 'ARCHIVE_BASE_0')
	assertEquals '6c9bd7e1cf88fdbfa0e75f694bf8b0e5' "$archive_hash"
	rm "${PLAYIT_WORKDIR}/cache/hashes"

	ARCHIVE_BASE_0_NAME='null'
	ARCHIVE_BASE_0_PATH='/dev/null'
	archive_hash=$(archive_hash_md5_computed 'ARCHIVE_BASE_0') 2>/dev/null
	assertEquals 'd41d8cd98f00b204e9800998ecf8427e' "$archive_hash"
}

test_archive_type() {
	local ARCHIVE_BASE_0_NAME ARCHIVE_BASE_0_TYPE ARCHIVE_BASE_0_PART1_NAME archive_type

	# Bypass the search for the archive path
	archive_path() {
		return 0
	}
	archive_guess_type_from_headers() {
		return 0
	}

	ARCHIVE_BASE_0_NAME='some_game_archive.tar.gz'
	archive_type=$(archive_type 'ARCHIVE_BASE_0')
	assertEquals 'tar.gz' "$archive_type"

	ARCHIVE_BASE_0_TYPE='zip'
	archive_type=$(archive_type 'ARCHIVE_BASE_0')
	assertEquals 'zip' "$archive_type"

	ARCHIVE_BASE_0_PART1_NAME='some_strange_game_archive.xyz'
	archive_type=$(archive_type 'ARCHIVE_BASE_0_PART1')
	assertEquals 'zip' "$archive_type"

	ARCHIVE_BASE_0_NAME='some_strange_game_archive.xyz'
	unset ARCHIVE_BASE_0_TYPE
	archive_type=$(archive_type 'ARCHIVE_BASE_0')
	assertNull "$archive_type"
}

test_archive_guess_type_from_name() {
	local archive_type

	archive_type=$(archive_guess_type_from_name 'some_game_archive.tar.gz')
	assertEquals 'tar.gz' "$archive_type"

	archive_type=$(archive_guess_type_from_name 'some_strange_game_archive.xyz')
	assertNull 'archive_guess_type_from_name hallucinated a type for an archive using an unknown extension.' "$archive_type"

	return 0
}

test_archive_extractor() {
	local ARCHIVE_BASE_0_EXTRACTOR archive_extractor

	ARCHIVE_BASE_0_EXTRACTOR='bsdtar'
	archive_extractor=$(archive_extractor 'ARCHIVE_BASE_0')
	assertEquals 'bsdtar' "$archive_extractor"

	archive_extractor=$(archive_extractor 'ARCHIVE_BASE_0_PART1')
	assertEquals 'bsdtar' "$archive_extractor"

	unset ARCHIVE_BASE_0_EXTRACTOR
	archive_extractor=$(archive_extractor 'ARCHIVE_BASE_0')
	assertNull "$archive_extractor"
}

test_archive_extractor_options() {
	local ARCHIVE_BASE_0_EXTRACTOR_OPTIONS archive_extractor_options

	ARCHIVE_BASE_0_EXTRACTOR_OPTIONS='--gog'
	archive_extractor_options=$(archive_extractor_options 'ARCHIVE_BASE_0')
	assertEquals '--gog' "$archive_extractor_options"

	unset ARCHIVE_BASE_0_EXTRACTOR_OPTIONS
	archive_extractor_options=$(archive_extractor_options 'ARCHIVE_BASE_0')
	assertNull "$archive_extractor_options"
}
