// Copyright 2017 Istio 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
	}
}
