/*
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"

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

const (
	keyAttrsName = "apigeeKeyAttributes"
	keyAttrsDesc = "Set attributes based on an Apigee API key"

	keyParam           = "apiKey"
	pathParam          = "requestPath"
	successParam       = "success"
	successStringParam = "successString"
	clientIDParam      = "clientID"
	appNameParam       = "applicationName"
)

var keyAttrsConf = &config.VerifyKeyParams{}

type keyAttrsBuilder struct {
	adapter.DefaultBuilder
}

type keyAttrsGenerator struct {
	env          adapter.Env
	applications *applicationManager
}

func newKeyAttrsBuilder() adapter.AttributesGeneratorBuilder {
	return keyAttrsBuilder{
		adapter.NewDefaultBuilder(keyAttrsName, keyAttrsDesc, keyAttrsConf),
	}
}

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

func (b keyAttrsBuilder) BuildAttributesGenerator(env adapter.Env, c adapter.Config) (adapter.AttributesGenerator, error) {
	cfg := c.(*config.VerifyKeyParams)
	g := &keyAttrsGenerator{
		env:          env,
		applications: newApplicationManager(env, defaultAppLifetime, getVerifyPath(cfg)),
	}
	env.Logger().Infof("Created Apigee attributes generator to invoke \"%s\"", g.applications.checkURL)

	return g, nil
}

func (g *keyAttrsGenerator) Generate(in map[string]interface{}) (map[string]interface{}, error) {
	key := getString(in, keyParam)
	if key == "" {
		return nil, fmt.Errorf("Cannot verify API key: value of \"%s\" not found", keyParam)
	}
	path := getString(in, pathParam)
	if path == "" {
		return nil, fmt.Errorf("Cannot verify API key: value of \"%s\" not found", pathParam)
	}

	app, err := g.applications.get(key)
	if err != nil {
		g.env.Logger().Errorf("Error verifying API key: %s", err)
		return nil, err
	}

	out := make(map[string]interface{})
	out[successParam] = app.valid
	out[successStringParam] = fmt.Sprintf("%v", app.valid)
	if app.valid {
		out[clientIDParam] = app.clientID
		out[appNameParam] = app.name
	}
	return out, nil
}

func (g *keyAttrsGenerator) Close() error {
	return nil
}
