package cryptparse

import (
	`bytes`
	`encoding/pem`
)

// Bytes returns a combined PEM bytes of all blocks in a PemBlocks. Any nil, empty, or otherwise invalid blocks are skipped.
func (p *PemBlocks) Bytes() (combined []byte) {

	var err error
	var buf *bytes.Buffer = new(bytes.Buffer)

	for _, block := range p.Split() {
		if block == nil || block.Bytes == nil || block.Type == "" {
			continue
		}
		// We've ruled out "contextual" errors, so we ignore it here.
		if err = pem.Encode(buf, block); err != nil {
			continue
		}
	}

	combined = buf.Bytes()
	_ = err

	return
}

// BytesStrict is like Bytes but is much more strict/safe (invalid/empty/nil blocks are not skipped) and will return any errors on encoding.
func (p *PemBlocks) BytesStrict() (combined []byte, err error) {

	var buf *bytes.Buffer = new(bytes.Buffer)

	for _, block := range p.Split() {
		if err = pem.Encode(buf, block); err != nil {
			return
		}
	}

	combined = buf.Bytes()

	return
}

// BytesSplit returns separate PEM bytes of each block in a PemBlocks. Any nil, empty, or otherwise invalid blocks are skipped.
func (p *PemBlocks) BytesSplit() (pems [][]byte) {

	var b []byte

	for _, block := range p.Split() {
		if block == nil || block.Bytes == nil || block.Type == "" {
			continue
		}
		// We've ruled out "contextual" errors, so we ignore it here.
		b = pem.EncodeToMemory(block)
		pems = append(pems, b)
	}

	return
}

// BytesSplitStrict is like BytesSplit but is much more strict/safe (invalid/empty/nil blocks are not skipped) and will return any errors on encoding.
func (p *PemBlocks) BytesSplitStrict() (pems [][]byte, err error) {

	var buf *bytes.Buffer = new(bytes.Buffer)

	for _, block := range p.Split() {
		buf.Reset()
		if err = pem.Encode(buf, block); err != nil {
			return
		}
		pems = append(pems, buf.Bytes())
	}

	return
}

// Split returns a more primitive-friendly representation of a PemBlocks.
func (p *PemBlocks) Split() (native []*pem.Block) {

	if p == nil {
		return
	}

	native = *p

	return
}