/**
 * 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 image

import (
	"encoding/binary"
	"fmt"
	"io"
	"io/ioutil"
	"os"

	"github.com/apache/mynewt-artifact/errors"
	"github.com/apache/mynewt-artifact/sec"
)

const (
	IMAGE_MAGIC              = 0x96f3b83d /* Image header magic */
	IMAGE_TRAILER_MAGIC      = 0x6907     /* TLV info magic */
	IMAGE_PROT_TRAILER_MAGIC = 0x6908     /* Protected TLV info magic */
)

const (
	IMAGE_HEADER_SIZE  = 32
	IMAGE_TRAILER_SIZE = 4
	IMAGE_TLV_SIZE     = 4 /* Plus `value` field. */
)

/*
 * Image header flags.
 */
const (
	IMAGE_F_PIC          = 0x00000001
	IMAGE_F_ENCRYPTED    = 0x00000004 /* encrypted image */
	IMAGE_F_NON_BOOTABLE = 0x00000010 /* non bootable image */
)

/*
 * Image trailer TLV types.
 */
const (
	IMAGE_TLV_KEYHASH   = 0x01
	IMAGE_TLV_SHA256    = 0x10
	IMAGE_TLV_RSA2048   = 0x20
	IMAGE_TLV_ECDSA224  = 0x21
	IMAGE_TLV_ECDSA256  = 0x22
	IMAGE_TLV_RSA3072   = 0x23
	IMAGE_TLV_ED25519   = 0x24
	IMAGE_TLV_ENC_RSA   = 0x30
	IMAGE_TLV_ENC_KEK   = 0x31
	IMAGE_TLV_ENC_EC256 = 0x32
	IMAGE_TLV_AES_NONCE = 0x50
	IMAGE_TLV_SECRET_ID = 0x60
	IMAGE_TLV_SECTION   = 0xa3
)

var imageTlvTypeNameMap = map[uint8]string{
	IMAGE_TLV_KEYHASH:   "KEYHASH",
	IMAGE_TLV_SHA256:    "SHA256",
	IMAGE_TLV_RSA2048:   "RSA2048",
	IMAGE_TLV_ECDSA224:  "ECDSA224",
	IMAGE_TLV_ECDSA256:  "ECDSA256",
	IMAGE_TLV_RSA3072:   "RSA3072",
	IMAGE_TLV_ED25519:   "ED25519",
	IMAGE_TLV_ENC_RSA:   "ENC_RSA",
	IMAGE_TLV_ENC_KEK:   "ENC_KEK",
	IMAGE_TLV_ENC_EC256: "ENC_EC256",
	IMAGE_TLV_AES_NONCE: "AES_NONCE",
	IMAGE_TLV_SECRET_ID: "SEC_KEY_ID",
	IMAGE_TLV_SECTION:   "SECTION",
}

var imageTlvTypeSigTypeMap = map[uint8]sec.SigType{
	IMAGE_TLV_RSA2048:  sec.SIG_TYPE_RSA2048,
	IMAGE_TLV_ECDSA224: sec.SIG_TYPE_ECDSA224,
	IMAGE_TLV_ECDSA256: sec.SIG_TYPE_ECDSA256,
	IMAGE_TLV_RSA3072:  sec.SIG_TYPE_RSA3072,
	IMAGE_TLV_ED25519:  sec.SIG_TYPE_ED25519,
}

type ImageVersion struct {
	Major    uint8
	Minor    uint8
	Rev      uint16
	BuildNum uint32
}

type ImageHdr struct {
	Magic  uint32
	Pad1   uint32
	HdrSz  uint16
	ProtSz uint16
	ImgSz  uint32
	Flags  uint32
	Vers   ImageVersion
	Pad3   uint32
}

type ImageTlvHdr struct {
	Type uint8
	Pad  uint8
	Len  uint16
}

type ImageTlv struct {
	Header ImageTlvHdr
	Data   []byte
}

type ImageTrailer struct {
	Magic     uint16
	TlvTotLen uint16
}

type Image struct {
	Header   ImageHdr
	Pad      []byte
	Body     []byte
	ProtTlvs []ImageTlv
	Tlvs     []ImageTlv
}

type ImageOffsets struct {
	Header      int
	Body        int
	ProtTrailer int
	Trailer     int
	ProtTlvs    []int
	Tlvs        []int
	TotalSize   int
}

type Section struct {
	Name   string
	Size   int
	Offset int
}

func ImageTlvTypeIsValid(tlvType uint8) bool {
	_, ok := imageTlvTypeNameMap[tlvType]
	return ok
}

func ImageTlvTypeName(tlvType uint8) string {
	name, ok := imageTlvTypeNameMap[tlvType]
	if !ok {
		return "???"
	}

	return name
}

func ImageTlvTypeToSigType(tlvType uint8) (sec.SigType, bool) {
	typ, ok := imageTlvTypeSigTypeMap[tlvType]
	return typ, ok
}

func ImageTlvTypeIsSig(tlvType uint8) bool {
	return tlvType == IMAGE_TLV_RSA2048 ||
		tlvType == IMAGE_TLV_RSA3072 ||
		tlvType == IMAGE_TLV_ECDSA224 ||
		tlvType == IMAGE_TLV_ECDSA256 ||
		tlvType == IMAGE_TLV_ED25519
}

func ImageTlvTypeIsSecret(tlvType uint8) bool {
	return tlvType == IMAGE_TLV_ENC_RSA ||
		tlvType == IMAGE_TLV_ENC_KEK ||
		tlvType == IMAGE_TLV_ENC_EC256
}

func (ver ImageVersion) String() string {
	return fmt.Sprintf("%d.%d.%d.%d",
		ver.Major, ver.Minor, ver.Rev, ver.BuildNum)
}

func (tlv *ImageTlv) Clone() ImageTlv {
	return ImageTlv{
		Header: tlv.Header,
		Data:   append([]byte(nil), tlv.Data...),
	}
}

func (tlv *ImageTlv) Write(w io.Writer) (int, error) {
	totalSize := 0

	err := binary.Write(w, binary.LittleEndian, &tlv.Header)
	if err != nil {
		return totalSize, errors.Wrapf(err, "failed to write image TLV header")
	}
	totalSize += IMAGE_TLV_SIZE

	size, err := w.Write(tlv.Data)
	if err != nil {
		return totalSize, errors.Wrapf(err, "failed to write image TLV data")
	}
	totalSize += size

	return totalSize, nil
}

// Clone performs a deep copy of an image.
func (img *Image) Clone() Image {
	dup := Image{
		Header:   img.Header,
		Pad:      append([]byte(nil), img.Pad...),
		Body:     append([]byte(nil), img.Body...),
		ProtTlvs: make([]ImageTlv, len(img.ProtTlvs)),
		Tlvs:     make([]ImageTlv, len(img.Tlvs)),
	}

	for i, tlv := range img.ProtTlvs {
		dup.ProtTlvs[i] = tlv.Clone()
	}

	for i, tlv := range img.Tlvs {
		dup.Tlvs[i] = tlv.Clone()
	}

	return dup
}

// FindTlvIndicesIf searches an image for TLVs satisfying the given predicate
// and returns their indices.
func (img *Image) FindTlvIndicesIf(pred func(tlv ImageTlv) bool) []int {
	var idxs []int

	for i, tlv := range img.Tlvs {
		if pred(tlv) {
			idxs = append(idxs, i)
		}
	}

	return idxs
}

// FindTlvIndices searches an image for TLVs of the specified type and
// returns their indices.
func (img *Image) FindTlvIndices(tlvType uint8) []int {
	return img.FindTlvIndicesIf(func(tlv ImageTlv) bool {
		return tlv.Header.Type == tlvType
	})
}

// FindTlvIndices searches an image for TLVs satisfying the given predicate and
// returns them.
func (img *Image) FindTlvsIf(pred func(tlv ImageTlv) bool) []*ImageTlv {
	var tlvs []*ImageTlv

	idxs := img.FindTlvIndicesIf(pred)
	for _, idx := range idxs {
		tlvs = append(tlvs, &img.Tlvs[idx])
	}

	return tlvs
}

// FindTlvs retrieves all TLVs in an image's footer with the specified type.
func (img *Image) FindTlvs(tlvType uint8) []*ImageTlv {
	var tlvs []*ImageTlv

	idxs := img.FindTlvIndices(tlvType)
	for _, idx := range idxs {
		tlvs = append(tlvs, &img.Tlvs[idx])
	}

	return tlvs
}

// FindUniqueTlv retrieves a TLV in an image's footer with the specified
// type.  It returns an error if there is more than one TLV with this type.
func (i *Image) FindUniqueTlv(tlvType uint8) (*ImageTlv, error) {
	tlvs := i.FindTlvs(tlvType)
	if len(tlvs) == 0 {
		return nil, nil
	}
	if len(tlvs) > 1 {
		return nil, errors.Errorf("image contains %d TLVs with type %d",
			len(tlvs), tlvType)
	}

	return tlvs[0], nil
}

// RemoveTlvsIf removes all TLVs from an image that satisfy the supplied
// predicate.  It returns a slice of the removed TLVs.
func (i *Image) RemoveTlvsIf(pred func(tlv ImageTlv) bool) []ImageTlv {
	rmed := []ImageTlv{}

	for idx := 0; idx < len(i.Tlvs); {
		tlv := i.Tlvs[idx]
		if pred(tlv) {
			rmed = append(rmed, tlv)
			i.Tlvs = append(i.Tlvs[:idx], i.Tlvs[idx+1:]...)
		} else {
			idx++
		}
	}

	return rmed
}

// RemoveTlvsWithType removes from an image all TLVs with the specified type.
// It returns a slice of the removed TLVs.
func (i *Image) RemoveTlvsWithType(tlvType uint8) []ImageTlv {
	return i.RemoveTlvsIf(func(tlv ImageTlv) bool {
		return tlv.Header.Type == tlvType
	})
}

// FindProtTlvIndicesIf searches an image for TLVs satisfying the given
// predicate and returns their indices.
func (img *Image) FindProtTlvIndicesIf(pred func(tlv ImageTlv) bool) []int {
	var idxs []int

	for i, tlv := range img.ProtTlvs {
		if pred(tlv) {
			idxs = append(idxs, i)
		}
	}

	return idxs
}

// FindProtTlvIndices searches an image for TLVs of the specified type and
// returns their indices.
func (img *Image) FindProtTlvIndices(tlvType uint8) []int {
	return img.FindProtTlvIndicesIf(func(tlv ImageTlv) bool {
		return tlv.Header.Type == tlvType
	})
}

// FindTlvIndices searches an image for TLVs satisfying the given predicate and
// returns them.
func (img *Image) FindProtTlvsIf(pred func(tlv ImageTlv) bool) []*ImageTlv {
	var tlvs []*ImageTlv

	idxs := img.FindProtTlvIndicesIf(pred)
	for _, idx := range idxs {
		tlvs = append(tlvs, &img.ProtTlvs[idx])
	}

	return tlvs
}

// FindProtTlvs retrieves all TLVs in an image's footer with the specified type.
func (img *Image) FindProtTlvs(tlvType uint8) []*ImageTlv {
	var tlvs []*ImageTlv

	idxs := img.FindProtTlvIndices(tlvType)
	for _, idx := range idxs {
		tlvs = append(tlvs, &img.ProtTlvs[idx])
	}

	return tlvs
}

// FindProtUniqueTlv retrieves a TLV in an image's footer with the specified
// type.  It returns an error if there is more than one TLV with this type.
func (i *Image) FindProtUniqueTlv(tlvType uint8) (*ImageTlv, error) {
	tlvs := i.FindProtTlvs(tlvType)
	if len(tlvs) == 0 {
		return nil, nil
	}
	if len(tlvs) > 1 {
		return nil, errors.Errorf("image contains %d TLVs with type %d",
			len(tlvs), tlvType)
	}

	return tlvs[0], nil
}

// RemoveProtTlvsIf removes all TLVs from an image that satisfy the supplied
// predicate.  It returns a slice of the removed TLVs.
func (i *Image) RemoveProtTlvsIf(pred func(tlv ImageTlv) bool) []ImageTlv {
	rmed := []ImageTlv{}

	for idx := 0; idx < len(i.ProtTlvs); {
		tlv := i.ProtTlvs[idx]
		if pred(tlv) {
			rmed = append(rmed, tlv)
			i.ProtTlvs = append(i.ProtTlvs[:idx], i.ProtTlvs[idx+1:]...)

			i.Header.ProtSz -= uint16(IMAGE_TLV_SIZE + len(tlv.Data))
		} else {
			idx++
		}
	}

	if len(i.ProtTlvs) == 0 {
		i.Header.ProtSz = 0
	}

	return rmed
}

// RemoveProtTlvsWithType removes from an image all TLVs with the specified
// type.  It returns a slice of the removed TLVs.
func (i *Image) RemoveProtTlvsWithType(tlvType uint8) []ImageTlv {
	return i.RemoveProtTlvsIf(func(tlv ImageTlv) bool {
		return tlv.Header.Type == tlvType
	})
}

func (i *Image) FindAllTlvsIf(pred func(tlv ImageTlv) bool) []*ImageTlv {
	regTlvs := i.FindTlvsIf(pred)
	protTlvs := i.FindProtTlvsIf(pred)

	return append(regTlvs, protTlvs...)
}

func (i *Image) FindAllTlvs(tlvType uint8) []*ImageTlv {
	return i.FindAllTlvsIf(func(tlv ImageTlv) bool {
		return tlv.Header.Type == tlvType
	})
}

func (i *Image) FindAllUniqueTlv(tlvType uint8) (*ImageTlv, error) {
	tlvs := i.FindAllTlvs(tlvType)

	if len(tlvs) == 0 {
		return nil, nil
	}

	if len(tlvs) > 1 {
		return nil, errors.Errorf(
			"image contains too many TLVs with type %d: have=%d want<=1",
			tlvType, len(tlvs))
	}

	return tlvs[0], nil
}

// ProtTrailer constructs a protected ImageTrailer corresponding to the given
// image.
func (img *Image) ProtTrailer() ImageTrailer {
	trailer := ImageTrailer{
		Magic:     IMAGE_PROT_TRAILER_MAGIC,
		TlvTotLen: IMAGE_TRAILER_SIZE,
	}
	for _, tlv := range img.ProtTlvs {
		trailer.TlvTotLen += IMAGE_TLV_SIZE + tlv.Header.Len
	}

	return trailer
}

// Trailer constructs an ImageTrailer corresponding to the given image.
func (img *Image) Trailer() ImageTrailer {
	trailer := ImageTrailer{
		Magic:     IMAGE_TRAILER_MAGIC,
		TlvTotLen: IMAGE_TRAILER_SIZE,
	}
	for _, tlv := range img.Tlvs {
		trailer.TlvTotLen += IMAGE_TLV_SIZE + tlv.Header.Len
	}

	return trailer
}

// Hash retrieves the contents of an image's SHA256 TLV.
func (i *Image) Hash() ([]byte, error) {
	tlv, err := i.FindUniqueTlv(IMAGE_TLV_SHA256)
	if err != nil {
		return nil, errors.Wrapf(err, "failed to retrieve image hash")
	}

	if tlv == nil {
		return nil, errors.Errorf(
			"failed to retrieve image hash: image does not contain hash TLV")
	}

	return tlv.Data, nil
}

// CalcHash calculates a SHA256 of the given image.  initialHash should be nil
// for non-split-images.
func (i *Image) CalcHash(initialHash []byte) ([]byte, error) {
	return calcHash(initialHash, i.Header, i.Pad, i.Body, i.ProtTlvs)
}

// WritePlusOffsets writes a binary image to the given writer.  It returns
// the offsets of the image components that got written.
func (i *Image) WritePlusOffsets(w io.Writer) (ImageOffsets, error) {
	offs := ImageOffsets{}
	offset := 0

	offs.Header = offset

	err := binary.Write(w, binary.LittleEndian, &i.Header)
	if err != nil {
		return offs, errors.Wrapf(err, "failed to write image header")
	}
	offset += IMAGE_HEADER_SIZE

	err = binary.Write(w, binary.LittleEndian, i.Pad)
	if err != nil {
		return offs, errors.Wrapf(err, "failed to write image padding")
	}
	offset += len(i.Pad)

	offs.Body = offset
	size, err := w.Write(i.Body)
	if err != nil {
		return offs, errors.Wrapf(err, "failed to write image body")
	}
	offset += size

	if i.Header.ProtSz > 0 {
		protTrailer := i.ProtTrailer()
		offs.ProtTrailer = offset
		err = binary.Write(w, binary.LittleEndian, &protTrailer)
		if err != nil {
			return offs, errors.Wrapf(err, "failed to write image trailer")
		}
		offset += IMAGE_TRAILER_SIZE

		for _, tlv := range i.ProtTlvs {
			offs.ProtTlvs = append(offs.ProtTlvs, offset)
			size, err := tlv.Write(w)
			if err != nil {
				return offs, errors.Wrapf(err, "failed to write image TLV")
			}
			offset += size
		}
	}

	trailer := i.Trailer()
	offs.Trailer = offset
	err = binary.Write(w, binary.LittleEndian, &trailer)
	if err != nil {
		return offs, errors.Wrapf(err, "failed to write image trailer")
	}
	offset += IMAGE_TRAILER_SIZE

	for _, tlv := range i.Tlvs {
		offs.Tlvs = append(offs.Tlvs, offset)
		size, err := tlv.Write(w)
		if err != nil {
			return offs, errors.Wrapf(err, "failed to write image TLV")
		}
		offset += size
	}

	offs.TotalSize = offset

	return offs, nil
}

// Offsets returns the offsets of each of an image's components if it were
// serialized.
func (i *Image) Offsets() (ImageOffsets, error) {
	return i.WritePlusOffsets(ioutil.Discard)
}

// TotalSize returns the size of the image if it were serialized, in bytes.
func (i *Image) TotalSize() (int, error) {
	offs, err := i.Offsets()
	if err != nil {
		return 0, err
	}
	return offs.TotalSize, nil
}

// Write serializes and writes a Mynewt image.
func (i *Image) Write(w io.Writer) (int, error) {
	offs, err := i.WritePlusOffsets(w)
	if err != nil {
		return 0, err
	}

	return offs.TotalSize, nil
}

// WriteToFile writes a Mynewt image to a file.
func (i *Image) WriteToFile(filename string) error {
	f, err := os.OpenFile(filename, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
	if err != nil {
		return errors.Wrapf(err, "failed to open image destination file")
	}

	if _, err := i.Write(f); err != nil {
		return errors.Wrapf(err, "failed to write image")
	}

	return nil
}

// CollectSigs returns a slice of all signatures present in an image's
// trailer.
func (img *Image) CollectSigs() ([]sec.Sig, error) {
	var sigs []sec.Sig

	var keyHashTlv *ImageTlv
	for i, _ := range img.Tlvs {
		t := &img.Tlvs[i]

		if t.Header.Type == IMAGE_TLV_KEYHASH {
			if keyHashTlv != nil {
				return nil, errors.Errorf(
					"image contains keyhash tlv without subsequent signature")
			}
			keyHashTlv = t
		} else {
			sigType, ok := ImageTlvTypeToSigType(t.Header.Type)
			if ok {
				if keyHashTlv == nil {
					return nil, errors.Errorf(
						"image contains signature tlv without preceding keyhash")
				}

				sigs = append(sigs, sec.Sig{
					Type:    sigType,
					KeyHash: keyHashTlv.Data,
					Data:    t.Data,
				})

				keyHashTlv = nil
			}
		}
	}

	return sigs, nil
}

// CollectSecret finds the "secret" TLV in an image and returns its body.  It
// returns nil if there is no "secret" TLV.
func (img *Image) CollectSecret() ([]byte, error) {
	tlv, err := img.FindUniqueTlv(IMAGE_TLV_ENC_RSA)
	if err != nil {
		return nil, err
	}

	if tlv == nil {
		return nil, nil
	}

	return tlv.Data, nil
}

// ExtractSecret finds the "secret" TLV in an image, removes it, and returns
// its body.  It returns nil if there is no "secret" TLV.
func (img *Image) ExtractSecret() ([]byte, error) {
	tlvs := img.RemoveTlvsWithType(IMAGE_TLV_ENC_RSA)

	if len(tlvs) == 0 {
		return nil, nil
	}

	if len(tlvs) > 1 {
		return nil, errors.Errorf(
			"image contains >1 ENC_RSA TLVs (%d)", len(tlvs))
	}

	return tlvs[0].Data, nil
}

// Encrypt encrypts an image body and adds a "secret" TLV.  It does NOT set the
// "encrypted" flag in the image header.
func Encrypt(img Image, pubEncKey sec.PubEncKey) (Image, error) {
	dup := img.Clone()

	tlvp, err := dup.FindUniqueTlv(IMAGE_TLV_ENC_RSA)
	if err != nil {
		return dup, err
	}
	if tlvp != nil {
		return dup, errors.Errorf("image already contains an ENC_RSA TLV")
	}

	plainSecret, err := GeneratePlainSecret()
	if err != nil {
		return dup, err
	}

	cipherSecret, err := pubEncKey.Encrypt(plainSecret)
	if err != nil {
		return dup, err
	}

	body, err := sec.EncryptAES(dup.Body, plainSecret, nil)
	if err != nil {
		return dup, err
	}
	dup.Body = body

	tlv, err := GenerateEncTlv(cipherSecret)
	if err != nil {
		return dup, err
	}
	dup.Tlvs = append(dup.Tlvs, tlv)

	return dup, nil
}

// Decrypt decrypts an image body and strips the "secret" TLV.  It does NOT
// clear the "encrypted" flag in the image header.
func Decrypt(img Image, privEncKey sec.PrivEncKey) (Image, error) {
	dup := img.Clone()

	tlvs := dup.RemoveTlvsIf(func(tlv ImageTlv) bool {
		return ImageTlvTypeIsSecret(tlv.Header.Type)
	})
	if len(tlvs) != 1 {
		return dup, errors.Errorf(
			"failed to decrypt image: wrong count of \"secret\" TLVs; "+
				"have=%d want=1", len(tlvs))
	}

	cipherSecret := tlvs[0].Data
	plainSecret, err := privEncKey.Decrypt(cipherSecret)
	if err != nil {
		return img, err
	}

	body, err := sec.EncryptAES(dup.Body, plainSecret, nil)
	if err != nil {
		return img, err
	}

	dup.Body = body

	return dup, nil
}

// DecryptHw decrypts a hardware-encrypted image.  It does NOT strip the
// "nonce" or "secret ID" protected TLVs.
func DecryptHw(img Image, secret []byte) (Image, error) {
	dup := img.Clone()

	tlvs := dup.FindProtTlvs(IMAGE_TLV_AES_NONCE)
	if len(tlvs) != 1 {
		return dup, errors.Errorf(
			"failed to decrypt hw-encrypted image: "+
				"wrong count of AES nonce TLVs; have=%d want=1", len(tlvs))
	}
	nonce := tlvs[0].Data

	body, err := sec.EncryptAES(dup.Body, secret, nonce)
	if err != nil {
		return dup, err
	}

	dup.Body = body

	return dup, nil
}

// DecryptHw decrypts a hardware-encrypted image and strips the "nonce" and
// "secret ID" protected TLVs.
func DecryptHwFull(img Image, secret []byte) (Image, error) {
	var err error

	img, err = DecryptHw(img, secret)
	if err != nil {
		return img, err
	}

	img.RemoveProtTlvsWithType(IMAGE_TLV_AES_NONCE)
	img.RemoveProtTlvsWithType(IMAGE_TLV_SECRET_ID)

	return img, nil
}

// IsEncrypted indicates whether an image's "encrypted" flag is set.
func (img *Image) IsEncrypted() bool {
	return img.Header.Flags&IMAGE_F_ENCRYPTED != 0
}
