package utils

import (
	"mime/multipart"
	"strconv"
	"strings"

	"github.com/fiskerinc/cloud-services/pkg/common"
	"github.com/fiskerinc/cloud-services/pkg/utils"
)

// GetUpdatePackgeFormParser returns form parser function to parse FormData
func GetUpdateManifestFileFormParser() (utils.FormParser, *common.UpdateManifestFile) {
	data := common.UpdateManifestFile{
		WriteRegion: common.MemoryRegion{
			Length: 1, // Set to non-zero to pass init validation, actual value will be set and checked later
		},
	}

	return func(part *multipart.Part) error {
		var err error
		switch part.FormName() {
		case "manifest_ecu_id":
			data.UpdateManifestECUID, err = utils.PartReadInt64(part, 2048, 64)
		case "url":
			data.URL, err = utils.PartReadAll(part, 500)
		case "offset":
			data.WriteRegion.Offset, err = utils.PartReadUInt64(part, 255, 64)
		case "checksum":
			data.Checksum, err = utils.PartReadAll(part, 32)
		case "order":
			data.FileOrder, err = utils.PartReadInt(part, 255)
		case "signature":
			data.Signature, err = utils.PartReadAll(part, 129)
		case "type":
			value, err := utils.PartReadAll(part, 255)
			if err != nil {
				return err
			}
			data.FileType = convertFileType(value)
		case "parsed_file":
			stringBool, err := utils.PartReadAll(part, 32)
			if err != nil {
				return err
			}
			aBool, err := strconv.ParseBool(stringBool)
			if err != nil {
				return err
			}
			data.Parsed = &aBool
		}

		return err
	}, &data
}

func convertFileType(filetype string) common.ManifestFileType {
	value := strings.ToLower(filetype)

	if strings.Contains(value, string(common.Bootloader)) {
		return common.Bootloader
	}

	if strings.Contains(value, string(common.Software)) || strings.Contains(value, "sw") {
		return common.Software
	}

	if strings.Contains(value, string(common.Calibration)) {
		return common.Calibration
	}

	return common.Other
}
