/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package mfg

import (
	"crypto/sha256"

	"github.com/apache/mynewt-artifact/errors"
	"github.com/apache/mynewt-artifact/flash"
	"github.com/apache/mynewt-artifact/image"
	"github.com/apache/mynewt-artifact/manifest"
)

const MFG_BIN_IMG_FILENAME = "mfgimg.bin"
const MFG_HEX_IMG_FILENAME = "mfgimg.hex"
const MANIFEST_FILENAME = "manifest.json"

type Mfg struct {
	Bin  []byte
	Meta *Meta

	// Unused if Meta==nil.
	MetaOff int
}

// StripPadding produces a new byte slice by removing padding from an
// existing byte slice.  Padding is defined as a sequence of trailing bytes,
// all with the specified value.
func StripPadding(b []byte, eraseVal byte) []byte {
	var pad int
	for pad = 0; pad < len(b); pad++ {
		off := len(b) - pad - 1
		if b[off] != eraseVal {
			break
		}
	}

	return b[:len(b)-pad]
}

// AddPadding produces a new byte slice by adding extra bytes to the end of
// an existing slice.
func AddPadding(b []byte, eraseVal byte, padLen int) []byte {
	for i := 0; i < padLen; i++ {
		b = append(b, eraseVal)
	}
	return b
}

// Calculates the SHA256 hash, using the full manufacturing image as input.
// Hash-calculation algorithm is as follows:
// 1. Zero out the 32 bytes that will contain the hash.
// 2. Apply SHA256 to the result.
//
// This function assumes that the 32 bytes of hash data have already been
// zeroed.
func CalcHash(bin []byte) []byte {
	hash := sha256.Sum256(bin)
	return hash[:]
}

func (m *Mfg) RecalcHash(eraseVal byte) ([]byte, error) {
	// The hash TLV needs to be zeroed out in order to calculate the mfg
	// hash.  Duplicate the mfg object so that we don't modify the
	// original.
	dup := m.Clone()
	if dup.Meta != nil {
		dup.Meta.ClearHash()
	}

	bin, err := dup.Bytes(eraseVal)
	if err != nil {
		return nil, err
	}

	return CalcHash(bin), nil
}

// RefillHash replace's the contents of an mfgimage's SHA256 TLV with a newly
// calculated hash.
func (m *Mfg) RefillHash(eraseVal byte) error {
	if m.Meta == nil {
		return nil
	}
	tlv := m.Meta.FindFirstTlv(META_TLV_TYPE_HASH)
	if tlv == nil {
		return nil
	}

	// Calculate hash.
	hash, err := m.RecalcHash(eraseVal)
	if err != nil {
		return err
	}

	// Fill hash TLV.
	copy(tlv.Data, hash)

	return nil
}

// Hash retrieves the SHA256 value associated with an mfgimage.  If the
// mfgimage has an MMR with a SHA256 TLV, the TLV's value is returned.
// Otherwise, the hash is calculated and returned.
func (m *Mfg) Hash(eraseVal byte) ([]byte, error) {
	var hashBytes []byte

	if m.Meta != nil {
		hashBytes = m.Meta.Hash()
	}

	if hashBytes == nil {
		// No hash TLV; calculate hash manually.
		b, err := m.RecalcHash(eraseVal)
		if err != nil {
			return nil, err
		}
		hashBytes = b
	}

	return hashBytes, nil
}

// Bytes serializes an mfgimage into binary form.
func (m *Mfg) Bytes(eraseVal byte) ([]byte, error) {
	binCopy := make([]byte, len(m.Bin))
	copy(binCopy, m.Bin)

	metaBytes, err := m.Meta.Bytes()
	if err != nil {
		return nil, err
	}

	padLen := m.MetaOff + len(metaBytes) - len(binCopy)
	if padLen > 0 {
		binCopy = AddPadding(binCopy, eraseVal, padLen)
	}

	copy(binCopy[m.MetaOff:m.MetaOff+len(metaBytes)], metaBytes)

	return binCopy, nil
}

// Clone performs a deep copy of an mfgimage.
func (m *Mfg) Clone() Mfg {
	var meta *Meta
	if m.Meta != nil {
		metaDup := m.Meta.Clone()
		meta = &metaDup
	}

	bin := make([]byte, len(m.Bin))
	copy(bin, m.Bin)

	return Mfg{
		Bin:     bin,
		Meta:    meta,
		MetaOff: m.MetaOff,
	}
}

// ExtractFlashArea copies a portion out of a serialized mfgimage.  The
// offset and size to copy indicated by the provided FlashArea.
func (m *Mfg) ExtractFlashArea(area flash.FlashArea,
	eraseVal byte) ([]byte, error) {

	b, err := m.Bytes(eraseVal)
	if err != nil {
		return nil, err
	}

	if area.Offset >= len(b) {
		return nil, errors.Errorf(
			"flash area in mmr (\"%s\") is beyond end of mfgimage "+
				"(offset=%d mfgimg_len=%d)",
			area.Name, area.Offset, len(b))
	}

	// If the end of the target contains unwritten bytes, it gets truncated
	// from the mfgimage.
	end := area.Offset + area.Size
	if end > len(b) {
		end = len(b)
	}

	return b[area.Offset:end], nil
}

// Tlvs retrieves the slice of TLVs present in an mfgimage's MMR.  It returns
// nil if the mfgimage has no MMR.
func (m *Mfg) Tlvs() []MetaTlv {
	if m.Meta == nil {
		return nil
	} else {
		return m.Meta.Tlvs
	}
}

func (m *Mfg) extractImage(area flash.FlashArea, eraseVal byte) (image.Image, error) {
	bin, err := m.ExtractFlashArea(area, eraseVal)
	if err != nil {
		return image.Image{}, err
	}

	img, err := image.ParseImage(bin)
	if err != nil {
		return image.Image{}, errors.Wrapf(err,
			"failed to extract image from mfgimage; area=\"%s\"", area.Name)
	}

	return img, nil
}

// Constructs the set of images embedded in an mfgimage.
func (m *Mfg) ExtractImages(man manifest.MfgManifest) ([]image.Image, error) {
	var imgs []image.Image
	for _, t := range man.Targets {
		fa := man.FindFlashAreaDevOff(man.Device, t.Offset)
		if fa == nil {
			return nil, errors.Errorf(
				"no flash area in mfgimage corresponding to target \"%s\"",
				t.Name)
		}

		if !t.IsBoot() {
			img, err := m.extractImage(*fa, man.EraseVal)
			if err != nil {
				return nil, err
			}

			imgs = append(imgs, img)
		}
	}

	return imgs, nil
}
