package mfer

import (
	"bytes"
	"encoding/hex"
	"errors"
	"fmt"

	"github.com/multiformats/go-multihash"
)

// manifest holds the internal representation of a manifest file.
// Use NewManifestFromFile or NewManifestFromReader to load an existing manifest,
// or use Builder to create a new one.
type manifest struct {
	pbInner        *MFFile
	pbOuter        *MFFileOuter
	output         *bytes.Buffer
	signingOptions *SigningOptions
}

func (m *manifest) String() string {
	count := 0
	if m.pbInner != nil {
		count = len(m.pbInner.Files)
	}
	return fmt.Sprintf("<Manifest count=%d>", count)
}

// Files returns all file entries from a loaded manifest.
func (m *manifest) Files() []*MFFilePath {
	if m.pbInner == nil {
		return nil
	}
	return m.pbInner.Files
}

// signatureString generates the canonical string used for signing/verification.
// Format: MAGIC-UUID-MULTIHASH where UUID and multihash are hex-encoded.
// Requires pbOuter to be set with Uuid and Sha256 fields.
func (m *manifest) signatureString() (string, error) {
	if m.pbOuter == nil {
		return "", errors.New("pbOuter not set")
	}
	if len(m.pbOuter.Uuid) == 0 {
		return "", errors.New("UUID not set")
	}
	if len(m.pbOuter.Sha256) == 0 {
		return "", errors.New("SHA256 hash not set")
	}

	mh, err := multihash.Encode(m.pbOuter.Sha256, multihash.SHA2_256)
	if err != nil {
		return "", fmt.Errorf("failed to encode multihash: %w", err)
	}
	uuidStr := hex.EncodeToString(m.pbOuter.Uuid)
	mhStr := hex.EncodeToString(mh)
	return fmt.Sprintf("%s-%s-%s", MAGIC, uuidStr, mhStr), nil
}
