//
// Copyright (c) SAS Institute Inc.
//
// Licensed 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 starman

import (
	"archive/tar"
	"errors"
	"io"
	"io/ioutil"
	"strings"

	"github.com/sassoftware/relic/lib/readercounter"
)

const (
	mdPrefix  = ".metadata/"
	sigSuffix = ".sig"
	padSuffix = ".pad"
	blockSize = 512
)

type starmanInfo struct {
	mdblob, sigblob  []byte
	sigStart, sigEnd int64
	mdname           string
	md               TarMD
	hasSig           bool
}

func verifyMeta(r io.Reader) (*starmanInfo, error) {
	info := new(starmanInfo)
	rc := readercounter.New(r)
	tr := tar.NewReader(rc)
	hdr, err := tr.Next()
	if err != nil {
		return nil, err
	} else if !strings.HasPrefix(hdr.Name, mdPrefix) {
		return nil, errors.New("unsupported archive format")
	}
	info.mdname = hdr.Name
	info.mdblob, err = ioutil.ReadAll(tr)
	if err != nil {
		return nil, err
	}
	info.sigStart = (rc.N + blockSize - 1) / blockSize * blockSize

	hdr, err = tr.Next()
	if err != nil && err != io.EOF {
		return nil, err
	} else if hdr.Name == info.mdname+sigSuffix || hdr.Name == info.mdname+padSuffix {
		// read existing signature
		info.sigblob, err = ioutil.ReadAll(tr)
		if err != nil {
			return nil, err
		}
		if hdr.Name == info.mdname+sigSuffix {
			info.hasSig = true
		}
		info.sigEnd = (rc.N + blockSize - 1) / blockSize * blockSize
	} else {
		info.sigEnd = info.sigStart
	}
	if err := info.verifyFiles(tr); err != nil {
		return nil, err
	}
	return info, nil
}
