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

// TODO: key rotation

import(
	// ref: https://godoc.org/github.com/dgrijalva/jwt-go ,  https://github.com/dgrijalva/jwt-go
	jwt "github.com/dgrijalva/jwt-go"
	"fmt"
	"regexp"
	"net/http"
	"io/ioutil"
	"time"
)

const (
	defaultKeyFetch 	= time.Hour
	defaultPublicKeyURL	= "https://%s-%s.apigee.net/edgemicro-auth/publicKey"
)

type apigeeClaims struct {
	jwt.StandardClaims
	ClientId 		string `json:"client_id,omitempty"`
	ApplicationName        	string `json:"application_name,omitempty"`
	Scopes   		[]string `json:"scopes,omitempty"`
}

type jwtVerifier struct {
	parser 		  *jwt.Parser
	refresh    	  time.Duration
	public_key_rsa256 []byte
	// TODO add support for other algorithms
}

// return: verifier object that can be used to verify JWT
// input: keys
// TODO: input HMAC and ECDSA keys
func newVerifier(refresh time.Duration, public_key_url string) (*jwtVerifier){
	verifier_obj_pointer := new(jwtVerifier)

	// TODO: handle error
	public_key_rsa256_raw_data, _ := getHttp(public_key_url)

	// TODO: store parsed key
	verifier_obj_pointer.public_key_rsa256   = public_key_rsa256_raw_data
	verifier_obj_pointer.parser		 = new(jwt.Parser)
	// TODO: add more methods based on keys supplied to this function, while adding support for other algorithms
	verifier_obj_pointer.parser.ValidMethods = []string{"RS256"}

	return verifier_obj_pointer
}

// Verify a token and output the claims
func (this *jwtVerifier) Verify(to_verify_token string) (jwt.Claims, error) {

	// get byte stream of token
	to_verify_token_in_bytes := []byte(to_verify_token)

	// trim possible whitespace from token
	to_verify_token_in_bytes = regexp.MustCompile(`\s*$`).ReplaceAll(to_verify_token_in_bytes, []byte{})

	// Parse the token
	token, err := this.parser.ParseWithClaims(string(to_verify_token), &apigeeClaims{}, func(t *jwt.Token) (interface{}, error) {
		// this function should return right key to parse the token
		if(t.Method.Alg() == "RS256") {
			return jwt.ParseRSAPublicKeyFromPEM(this.public_key_rsa256)
		} else {
			return nil, fmt.Errorf("signing method not supported")
		}
	})

	if err != nil {
		return nil, fmt.Errorf("Couldn't parse token: %v", err)
	}

	if !token.Valid {
		return nil, fmt.Errorf("Token is invalid")
	}

	// return jwt.Claim object (https://github.com/dgrijalva/jwt-go/blob/master/claims.go#L11) (http://godoc.org/github.com/dgrijalva/jwt-go#Claims)
	return token.Claims, err
}

func getHttp(public_key_url string) ([]byte, error) {
	resp, err := http.Get(public_key_url)
	if err != nil {
		return nil, err
	}

	defer resp.Body.Close()

	if resp.StatusCode != 200 {
		return nil, fmt.Errorf("HTTP error fetching from url", public_key_url, " with response code ", resp.StatusCode)
	}

	return ioutil.ReadAll(resp.Body)
}