
import {Hex} from "../hex.js"
import {Base58} from "../base58.js"
import {Barname} from "./barname.js"

/**
 * Badge is a human-friendly presentation format for arbitrary binary data.
 *  - looks like "nomluc_rigpem.tg2bjNkjMh1H6M2b2EhD5V4x6XAqx9wyWddsBt"
 *  - the first bytes are shown in barname format
 *  - the rest of the data is in base58
 *  - designed to be a nice way to present 256-bit passport thumbprints
 *  - can be used for data of different lengths
 *  - preview size can be customized as 'leadCount', which defaults to 4
 */
export class Badge {
	static readonly separator = "."
	static readonly defaultLeadCount = 4

	readonly hex: string
	readonly string: string
	readonly preview: string

	constructor(
			public readonly bytes: Uint8Array,
			public readonly leadCount = Badge.defaultLeadCount,
		) {

		if (leadCount < 1)
			throw new Error(`badge leadCount must be greater than 0 (was ${leadCount})`)

		this.hex = Hex.string(this.bytes)
		this.preview = Barname.string(this.bytes.slice(0, leadCount))

		this.string = (bytes.length > leadCount)
			? `${this.preview}.${Base58.string(this.bytes.slice(leadCount))}`
			: this.preview
	}

	static parse(badge: string) {
		const [barname, b58] = badge.split(Badge.separator)

		// badge has a base58 component
		if (b58) {
			const appetizer = Barname.bytes(barname)
			const entree = Base58.bytes(b58)
			const bytes = new Uint8Array([...appetizer, ...entree])
			return new this(bytes, appetizer.length)
		}

		// badge is just a barname (no base58 part)
		else {
			const bytes = Barname.bytes(barname)
			return new this(bytes, bytes.length)
		}
	}

	static fromHex(hex: string, leadCount = this.defaultLeadCount) {
		const bytes = Hex.bytes(hex)
		return new this(bytes, leadCount)
	}

	static string(bytes: Uint8Array, leadCount = this.defaultLeadCount) {
		return new this(bytes, leadCount).string
	}

	static bytes(badge: string) {
		return this.parse(badge)
	}

	static hex(badge: string) {
		return this.parse(badge).hex
	}

	toString() {
		return this.string
	}
}

