package multihash

import (
	
	
	

	mhreg 
)

// ErrSumNotSupported is returned when the Sum function code is not implemented
var ErrSumNotSupported = mhreg.ErrSumNotSupported

var ErrLenTooLarge = mhreg.ErrLenTooLarge

// Sum obtains the cryptographic sum of a given buffer. The length parameter
// indicates the length of the resulting digest. Passing a negative value uses
// default length values for the selected hash function.
func ( []byte,  uint64,  int) (Multihash, error) {
	// Get the algorithm.
	,  := mhreg.GetVariableHasher(, )
	if  != nil {
		return nil, 
	}

	// Feed data in.
	if ,  := .Write();  != nil {
		return nil, 
	}

	return encodeHash(, , )
}

// SumStream obtains the cryptographic sum of a given stream. The length
// parameter indicates the length of the resulting digest. Passing a negative
// value uses default length values for the selected hash function.
func ( io.Reader,  uint64,  int) (Multihash, error) {
	// Get the algorithm.
	,  := mhreg.GetVariableHasher(, )
	if  != nil {
		return nil, 
	}

	// Feed data in.
	if _,  = io.Copy(, );  != nil {
		return nil, 
	}

	return encodeHash(, , )
}

func encodeHash( hash.Hash,  uint64,  int) (Multihash, error) {
	// Compute final hash.
	//  A new slice is allocated.  FUTURE: see other comment below about allocation, and review together with this line to try to improve.
	 := .Sum(nil)

	// Deal with any truncation.
	//  Unless it's an identity multihash.  Those have different rules.
	if  < 0 {
		 = .Size()
	}
	if len() <  {
		return nil, ErrLenTooLarge
	}
	if  >= 0 {
		if  == IDENTITY {
			if  != len() {
				return nil, fmt.Errorf("the length of the identity hash (%d) must be equal to the length of the data (%d)", , len())
			}
		}
		 = [:]
	}

	// Put the multihash metainfo bytes at the front of the buffer.
	//  FUTURE: try to improve allocations here.  Encode does several which are probably avoidable, but it's the shape of the Encode method arguments that forces this.
	return Encode(, )
}