package commands

import (
	"bufio"
	"encoding/binary"
	"io"
	"os"
)

type PrepareBinCommand struct {
	Version        string `long:"version" alias:"V" required:"true" description:"a version string of max 16 chars"`
	SourceFileName string `long:"src" alias:"i" required:"true" description:"input-filename"`
	DestFileName   string `long:"dest" alias:"o" required:"true" description:"output-filename"`
	MediaID        byte   `long:"mediaid" alias:"m" required:"true" description:"media identifier"`
}

func (command *PrepareBinCommand) Execute(args []string) error {
	inputFile, err := os.Open(command.SourceFileName)
	if err != nil {
		return err
	}
	defer inputFile.Close()
	inputFileStat, err := inputFile.Stat()
	if err != nil {
		return err
	}
	headerFileSize := inputFileStat.Size() + 32

	outputFile, err := os.Create(command.DestFileName)
	if err != nil {
		return err
	}
	defer outputFile.Close()

	outputWriter := bufio.NewWriter(outputFile)
	//Header
	headerBytes := []byte{command.MediaID, 0x32, 0xF6, 0x0C}
	_, err = outputWriter.Write(headerBytes)
	if err != nil {
		return err
	}

	totalSizeBytes := make([]byte, 4)
	binary.LittleEndian.PutUint32(totalSizeBytes, uint32(headerFileSize))
	_, err = outputWriter.Write(totalSizeBytes)
	if err != nil {
		return err
	}

	fillerBytes := make([]byte, 8)
	_, err = outputWriter.Write(fillerBytes)
	if err != nil {
		return err
	}
	versionTextBytes := make([]byte, 16)
	for i := 0; i < 16; i++ {
		if i < len(command.Version) {
			versionTextBytes[i] = command.Version[i]
		} else {
			versionTextBytes[i] = 0x20
		}
	}
	_, err = outputWriter.Write(versionTextBytes)
	if err != nil {
		return err
	}

	_, err = io.Copy(outputWriter, inputFile)
	if err != nil {
		return err
	}

	return nil
}