/*
Copyright 2017 The apid Authors

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 apigee

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"

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

const (
	checkName = "apigeeKeyChecker"
	checkDesc = "Verify an API key from a parameter"
)

var checkConf = &config.VerifyKeyParams{}

type keyCheckBuilder struct {
	adapter.DefaultBuilder
}

type keyChecker struct {
	keyParam     string
	organization string
	environment  string
}

type APIKeyBody struct {
	APIKey string `json:"apiKey"`
}

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

func (keyCheckBuilder) NewListsAspect(env adapter.Env, c adapter.Config) (adapter.ListsAspect, error) {
	return newKeyChecker(c.(*config.VerifyKeyParams))
}

func newKeyChecker(c *config.VerifyKeyParams) (*keyChecker, error) {
	return &keyChecker{
		keyParam:     c.KeyParameter,
		organization: c.Organization,
		environment:  c.Environment,
	}, nil
}

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) {
	fmt.Printf("*** Going to check \"%s\" against \"%s\"\n", symbol, l.organization)

	edge_url := "https://" + l.organization + "-" + l.environment + ".apigee.net/edgemicro-auth/verifyApiKey"

	fmt.Printf("*** edge_url  \"%s\"\n", edge_url)

	return verifyApiKey(symbol, edge_url), nil
}

func verifyApiKey(apiKey string, uri string) bool {
	apiKeyBody := APIKeyBody{
		APIKey: apiKey,
	}
	serializedBody, _ := json.Marshal(&apiKeyBody)
	req, _ := http.NewRequest("POST", uri, bytes.NewBuffer(serializedBody))
	req.Header.Add("x-dna-api-key", apiKey)
	req.Header.Add("content-type", "application/json")
	client := &http.Client{}
	resp, _ := client.Do(req)
	if resp.StatusCode != 200 {
		return false
	} else {
		return true
	}
}
