// 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 keyset

import (
	"fmt"

	tinkpb "github.com/google/tink/proto/tink_go_proto"
)

// ValidateKeyVersion checks whether the given version is valid. The version is valid
// only if it is the range [0..maxExpected]
func ValidateKeyVersion(version, maxExpected uint32) error {
	if version > maxExpected {
		return fmt.Errorf("key has version %v; only keys with version in range [0..%v] are supported",
			version, maxExpected)
	}
	return nil
}

// Validate validates the given key set.
// Returns nil if it is valid; an error otherwise.
func Validate(keyset *tinkpb.Keyset) error {
	if keyset == nil {
		return fmt.Errorf("Validate() called with nil")
	}
	if len(keyset.Key) == 0 {
		return fmt.Errorf("empty keyset")
	}
	primaryKeyID := keyset.PrimaryKeyId
	hasPrimaryKey := false
	for _, key := range keyset.Key {
		if err := validateKey(key); err != nil {
			return err
		}
		if key.Status == tinkpb.KeyStatusType_ENABLED && key.KeyId == primaryKeyID {
			if hasPrimaryKey {
				return fmt.Errorf("keyset contains multiple primary keys")
			}
			hasPrimaryKey = true
		}
	}
	if !hasPrimaryKey {
		return fmt.Errorf("keyset does not contain a valid primary key")
	}
	return nil
}

/*
validateKey validates the given key.
Returns nil if it is valid; an error otherwise.
*/
func validateKey(key *tinkpb.Keyset_Key) error {
	if key == nil {
		return fmt.Errorf("ValidateKey() called with nil")
	}
	if key.KeyId == 0 {
		return fmt.Errorf("key has zero key id: %d", key.KeyId)
	}
	if key.KeyData == nil {
		return fmt.Errorf("key %d has no key data", key.KeyId)
	}
	if key.OutputPrefixType != tinkpb.OutputPrefixType_TINK &&
		key.OutputPrefixType != tinkpb.OutputPrefixType_LEGACY &&
		key.OutputPrefixType != tinkpb.OutputPrefixType_RAW &&
		key.OutputPrefixType != tinkpb.OutputPrefixType_CRUNCHY {
		return fmt.Errorf("key %d has unknown prefix", key.KeyId)
	}
	if key.Status != tinkpb.KeyStatusType_ENABLED &&
		key.Status != tinkpb.KeyStatusType_DISABLED &&
		key.Status != tinkpb.KeyStatusType_DESTROYED {
		return fmt.Errorf("key %d has unknown status", key.KeyId)
	}
	return nil
}
