/*
Copyright 2017 Google 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 adapter

import (
	"fmt"
	"net/url"

	"github.com/apid/istioApigeeAdapter/adapter/config"
	"istio.io/mixer/pkg/adapter"
)

const (
	checkName        = "apigeeKeyChecker"
	checkDesc        = "Verify an API key from a parameter"
	verifyKeyPath    = "/verifyApiKey"
	defaultVerifyURL = "https://%s-%s.apigee.net/edgemicro-auth"
)

var checkConf = &config.VerifyKeyParams{}

type keyCheckBuilder struct {
	adapter.DefaultBuilder
}

type keyChecker struct {
	env         adapter.Env
	application *applicationManager
}

func newKeyCheckBuilder() adapter.ListsBuilder {
	return keyCheckBuilder{
		adapter.NewDefaultBuilder(checkName, checkDesc, checkConf),
	}
}

func (b keyCheckBuilder) ValidateConfig(c adapter.Config) *adapter.ConfigErrors {
	return validateKeyParams(c)
}

func validateKeyParams(c adapter.Config) (ce *adapter.ConfigErrors) {
	cfg := c.(*config.VerifyKeyParams)
	if cfg.Organization == "" {
		ce = ce.Appendf("organization", "Organization parameter must be specified")
	}
	if cfg.Environment == "" {
		ce = ce.Appendf("environment", "Environment parameter must be specified")
	}
	if cfg.VerificationURL != "" {
		_, err := url.Parse(cfg.VerificationURL)
		if err != nil {
			ce = ce.Appendf("verificationURL", "Invalid verification URL: %s", err)
		}
	}
	return
}

func (b keyCheckBuilder) NewListsAspect(env adapter.Env, c adapter.Config) (adapter.ListsAspect, error) {
	cfg := c.(*config.VerifyKeyParams)
	kc := &keyChecker{
		env:         env,
		application: newApplicationManager(env, defaultAppLifetime, getVerifyPath(cfg)),
	}
	env.Logger().Infof("Created Apigee Key Checker to invoke \"%s\"", kc.application.checkURL)

	return kc, nil
}

func getVerifyPath(cfg *config.VerifyKeyParams) string {
	var basePath string

	if cfg.VerificationURL == "" {
		basePath = fmt.Sprintf(defaultVerifyURL, cfg.Organization, cfg.Environment)
	} else {
		basePath = cfg.VerificationURL
	}
	return basePath + verifyKeyPath
}

func (l *keyChecker) Close() error {
	return nil
}

// CheckList is part of the interface for a "list checker" adapter. It's the part that
// gets whatever the value is (we want it to be the API key in our case) and checks it.

// Test command ./bazel-bin/cmd/client/mixc check -a target.service=f.default.svc.cluster.local --stringmap_attributes request.headers=x-api-key:1tu9pl04Srua2MtsAGtu6ViPxSYSSX2I

func (l *keyChecker) CheckList(symbol string) (bool, error) {
	app, err := l.application.get(symbol)
	if err != nil {
		l.env.Logger().Errorf("Error verifying API key: %s", err)
		return false, err
	}
	return app.valid, nil
}
