/*
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 (
	"bytes"
	"encoding/base64"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"net/http"
	"strings"
	"sync"
	"time"

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

const (
	defaultAppLifetime = 5 * time.Second
)

type application struct {
	clientID    string
	valid       bool
	expiration  time.Time
	name        string
	apiProducts []string
}

type applicationJWT struct {
	ClientID        string   `json:"client_id"`
	ApplicationName string   `json:"application_name"`
	APIProducts     []string `json:"api_product_list"`
}

type applicationManager struct {
	env      adapter.Env
	lifetime time.Duration
	cache    map[string]*application
	checkURL string
	latch    *sync.Mutex
}

func newApplicationManager(env adapter.Env, lifetime time.Duration, checkURL string) *applicationManager {
	return &applicationManager{
		env:      env,
		lifetime: lifetime,
		checkURL: checkURL,
		cache:    make(map[string]*application),
		latch:    &sync.Mutex{},
	}
}

func (a *applicationManager) get(key string) (*application, error) {
	app := a.cacheGet(key)
	if app != nil {
		return app, nil
	}

	app, err := a.lookupKey(key)
	if err != nil {
		return nil, err
	}
	a.cachePut(key, app)
	return app, nil
}

func (a *applicationManager) cacheGet(key string) *application {
	a.latch.Lock()
	app := a.cache[key]
	if app != nil && app.expiration.Before(time.Now()) {
		delete(a.cache, key)
		app = nil
	}
	a.latch.Unlock()
	return app
}

func (a *applicationManager) cachePut(key string, app *application) {
	a.latch.Lock()
	a.cache[key] = app
	a.latch.Unlock()
}

func (a *applicationManager) lookupKey(key string) (*application, error) {
	apiKeyBody := common.VerifyAPIKeyRequest{
		Key: key,
	}
	requestBody, _ := json.Marshal(&apiKeyBody)

	resp, err := http.DefaultClient.Post(a.checkURL, "application/json",
		bytes.NewBuffer(requestBody))
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	if resp.StatusCode == 200 {
		return a.parseApplication(resp.Body)

	} else if resp.StatusCode == 401 {
		return &application{
			clientID:   key,
			valid:      false,
			expiration: time.Now().Add(a.lifetime),
		}, nil

	} else {
		return nil, fmt.Errorf("HTTP error looking up application: %d", resp.StatusCode)
	}
}

func (a *applicationManager) parseApplication(r io.Reader) (*application, error) {
	var keyResponse common.VerifyAPIKeyResponse
	jr := json.NewDecoder(r)
	err := jr.Decode(&keyResponse)
	if err != nil {
		return nil, fmt.Errorf("Invalid JSON in API key response: %s", err)
	}

	// We got back a JWT, but we don't need to verify it -- just parse the JSON we need
	parts := strings.Split(keyResponse.Token, ".")
	if len(parts) != 3 {
		return nil, errors.New("Invalid JWT returned")
	}
	// base64 from Apigee is unpadded, so use "raw" encoding here.
	rawJWT, err := base64.RawStdEncoding.DecodeString(parts[1])
	if err != nil {
		return nil, fmt.Errorf("Error decoding JWT base 64: from \"%s\", %s", keyResponse.Token, err)
	}

	var jwt applicationJWT
	err = json.Unmarshal(rawJWT, &jwt)
	if err != nil {
		return nil, fmt.Errorf("Error decoding JWT json: %s", err)
	}

	a.env.Logger().Infof("Looked up data for application %s", jwt.ApplicationName)

	return &application{
		clientID:    jwt.ClientID,
		valid:       true,
		expiration:  time.Now().Add(a.lifetime),
		name:        jwt.ApplicationName,
		apiProducts: jwt.APIProducts,
	}, nil
}
