// Copyright 2019 Drone IO, 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 registry

import (
	"context"

	"github.com/drone/drone/core"
	"github.com/drone/drone/logger"
	"github.com/drone/drone/plugin/registry/auths"
)

// Static returns a new static credentials controller.
func Static(secrets []*core.Secret) core.RegistryService {
	return &staticController{secrets: secrets}
}

type staticController struct {
	secrets []*core.Secret
}

func (c *staticController) List(ctx context.Context, in *core.RegistryArgs) ([]*core.Registry, error) {
	static := map[string]*core.Secret{}
	for _, secret := range c.secrets {
		static[secret.Name] = secret
	}

	var results []*core.Registry
	for _, name := range in.Pipeline.PullSecrets {
		logger := logger.FromContext(ctx).WithField("name", name)
		logger.Trace("registry: database: find secret")

		secret, ok := static[name]
		if !ok {
			logger.Trace("registry: database: cannot find secret")
			continue
		}

		// The secret can be restricted to non-pull request
		// events. If the secret is restricted, return
		// empty results.
		if secret.PullRequest == false &&
			in.Build.Event == core.EventPullRequest {
			logger.Trace("registry: database: pull_request access denied")
			continue
		}

		logger.Trace("registry: database: secret found")
		parsed, err := auths.ParseString(secret.Data)
		if err != nil {
			logger.WithError(err).Error("registry: database: parsing error")
			return nil, err
		}

		results = append(results, parsed...)
	}
	return results, nil
}
