import os
import struct
import sys

# CFile
class CFile:
	def ReadImage(FileName):
		with open(FileName,'rb') as f:
			Data=f.read()

		return Data

	def WriteImage(FileName,Data):
		with open(FileName, 'wb') as f:
			f.write(Data)

	def FindFile(FilePath):
		FindFileNameList = glob.glob(FilePath)
		return (len(FindFileNameList) > 0)


# ファイル一覧取得
def list_files(directory):
	"""指定されたディレクトリ以下のファイル一覧を再帰的に取得する。

	Args:
		directory (str): ファイル一覧を取得するディレクトリのパス。

	Returns:
		list: ファイルのフルパスのリスト。
	"""
	file_list = []
	for root, _, files in os.walk(directory):
		for file in files:
			# ファイルの絶対パスを取得
			absolute_path = os.path.join(root, file)
			# directoryからの相対パスを取得
			relative_path = os.path.relpath(absolute_path, start=directory)
			file_list.append(relative_path)
	return file_list


# メイン
def Main():
	# コマンドライン引数
	args = sys.argv
	if (len(args) < 3):
		print("Arg error: HPKPacker.py (OutputFileName) (FolderName) (PrePath)")
		return
	
	OutputFileName = args[1]
	FolderName = args[2]
	PrePath = args[3]

	# ファイルリストを取得する
	file_list = list_files(FolderName)
	#print('\n'.join(file_list))

	# ファイル情報読み込み
	FileDataList = []

	for FilePath in file_list:
		FileFullPath = os.path.join(FolderName, FilePath)

		FileSize = os.path.getsize(FileFullPath)

		FileDataList.append((0, FilePath, 0, FileSize, FileSize))

		print(FilePath + ", " + str(FileSize))

	# ファイルイメージ作成
	FileOffsetWritePosList = []

	BinImage = bytearray()

	BinImage.extend('HPK'.encode('utf-8'))
	BinImage.append(0)

	BinImage.extend(struct.pack('<I', 0))	 # Version

	BinImage.extend(struct.pack('<I', len(file_list)))	 # Numof

	for FileType,FilePath,FileOffset,FileSize,DecodeSize in FileDataList:
		BinImage.extend((PrePath + '\\' + FilePath).encode('utf-8'))
		BinImage.append(0)

		BinImage.extend(struct.pack('<I', FileType))

		FileOffsetWritePosList.append(len(BinImage))

		BinImage.extend(struct.pack('<I', FileOffset))
		BinImage.extend(struct.pack('<I', FileSize))
		BinImage.extend(struct.pack('<I', DecodeSize))

	n = 0;

	for FileType,FilePath,FileOffset,FileSize,DecodeSize in FileDataList:
		FileFullPath = os.path.join(FolderName, FilePath)

		FileImage = CFile.ReadImage(FileFullPath)

		FileOffset = len(BinImage)

		FileOffsetWritePos = FileOffsetWritePosList[n]
		n += 1

		BinImage[FileOffsetWritePos:FileOffsetWritePos+4] = struct.pack('<I', FileOffset)

		BinImage.extend(FileImage)

	# ファイル書き込み
	CFile.WriteImage(OutputFileName, BinImage)
	

# 関数実行 
Main()
