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

import (
	"compress/gzip"
	"encoding/json"
	"fmt"
	"net"
	"net/http"
	"sync"
	"time"

	"github.com/SermoDigital/jose/crypto"
	"github.com/SermoDigital/jose/jws"
	"github.com/SermoDigital/jose/jwt"
	"github.com/apid/istioApigeeAdapter/common"
	"github.com/julienschmidt/httprouter"
)

var mockInit = &sync.Once{}

const (
	ValidAPIKey1          = "12345"
	ValidAPIKeyNoProducts = "23456"
	ValidPublishKey       = "aaaaaa"
	ValidPublishSecret    = "bbbbbb"
)

type MockServer struct {
	listener         net.Listener
	analyticsRecords []common.AnalyticsRecord
}

func StartMockServer(port int) (*MockServer, error) {
	mockInit.Do(makeKeys)

	l, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
	if err != nil {
		return nil, err
	}

	ms := &MockServer{
		listener: l,
	}

	router := httprouter.New()
	router.GET("/publicKey", ms.getPublicKey)
	router.GET("/products", ms.getProducts)
	router.POST("/verifyApiKey", ms.getAPIKey)
	router.POST("/edgemicro/axpublisher/organization/:org/environment/:env", ms.publishAnalytics)
	router.GET("/edgemicro/region/organization/:org/environment/:env", ms.getRegion)

	go func() {
		http.Serve(l, router)
	}()

	return ms, nil
}

func (m *MockServer) Address() string {
	return m.listener.Addr().String()
}

func (m *MockServer) Stop() {
	m.listener.Close()
}

func (m *MockServer) GetAnalyticsRecords() []common.AnalyticsRecord {
	return m.analyticsRecords
}

func (m *MockServer) getPublicKey(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
	w.Header().Set("content-type", "text/plain")
	w.Write(mockCertPEM)
}

func (m *MockServer) getProducts(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
	now := time.Now()
	p := []common.APIProduct{
		{
			Name:           "TestProduct1",
			DisplayName:    "First Product",
			Description:    "First test product",
			CreatedAt:      now.UnixNano(),
			CreatedBy:      "foo@bar.com",
			LastModifiedAt: now.UnixNano(),
			LastModifiedBy: "foo@bar.com",

			APIResources: []string{"/**"},
			ApprovalType: "auto",
			Attributes: []common.Attribute{
				{
					Name:  "access",
					Value: "public",
				},
			},
			Environments:  []string{"test", "prod"},
			Proxies:       []string{"ProxyOne"},
			Quota:         "10",
			QuotaInterval: "1",
			QuotaTimeUnit: "minute",
		},
	}
	pl := common.APIProductResponse{
		Products: p,
	}

	w.Header().Set("content-type", "application/json")

	enc := json.NewEncoder(w)
	enc.Encode(pl)
}

func (m *MockServer) getAPIKey(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
	if r.Header.Get("content-type") != "application/json" {
		// That's what the existing service does
		sendFault(w, 404, "Failed to resolve API Key variable apikey",
			"steps.oauth.v2.FailedToResolveAPIKey")
		return
	}

	var request common.VerifyAPIKeyRequest
	defer r.Body.Close()
	dec := json.NewDecoder(r.Body)
	err := dec.Decode(&request)
	if err != nil {
		// Again, what existing service does
		sendFault(w, 500, "Failed to execute the ExtractVariables: Extract-API-Key",
			"steps.extractvariables.ExecutionFailed")
		return
	}

	var returnedJwt jwt.JWT

	switch request.Key {
	case ValidAPIKey1:
		returnedJwt = makeJWT1()
	case ValidAPIKeyNoProducts:
		returnedJwt = makeJWT2()
	default:
		// We actually do return 401 in this case!
		sendFault(w, 401,
			fmt.Sprintf("API key %s is not valid", request.Key),
			"steps.oauth.v2.FailedToResolveAPIKey")
		return
	}

	bod, err := returnedJwt.Serialize(mockKey)
	if err != nil {
		sendFault(w, 500, err.Error(), "JWT")
		return
	}

	tok := common.VerifyAPIKeyResponse{
		Token: string(bod),
	}
	w.Header().Set("content-type", "application/json")
	enc := json.NewEncoder(w)
	enc.Encode(&tok)
}

func (m *MockServer) publishAnalytics(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
	user, pw, aok := r.BasicAuth()
	if !aok || user != ValidPublishKey || pw != ValidPublishSecret {
		w.WriteHeader(401)
		return
	}
	if r.Header.Get("content-type") != "application/json" {
		sendAnalyticsResponse(w, 0, 1)
		return
	}

	var req common.AnalyticsRequest
	var err error
	defer r.Body.Close()

	if r.Header.Get("content-encoding") == "" {
		dec := json.NewDecoder(r.Body)
		err = dec.Decode(&req)
	} else if r.Header.Get("content-encoding") == "gzip" {
		zr, _ := gzip.NewReader(r.Body)
		dec := json.NewDecoder(zr)
		err = dec.Decode(&req)
	}

	if err != nil {
		// This is what the existing service does
		sendFault(w, 500, "Failed to execute JavaCallout. not a JSON Object",
			"steps.javacallout.ExecutionError")
		return
	}

	// For now we just accept it all. We'll add some validation in the future.
	m.analyticsRecords = append(m.analyticsRecords, req.Records...)
	sendAnalyticsResponse(w, len(req.Records), 0)
}

func sendAnalyticsResponse(w http.ResponseWriter, accepted, rejected int) {
	resp := &common.AnalyticsResponse{
		Accepted: accepted,
		Rejected: rejected,
	}
	w.Header().Set("content-type", "application/json")
	enc := json.NewEncoder(w)
	enc.Encode(resp)
}

func (m *MockServer) getRegion(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
	user, pw, aok := r.BasicAuth()
	if !aok || user != ValidPublishKey || pw != ValidPublishSecret {
		w.WriteHeader(401)
		return
	}

	rr := common.RegionResponse{
		Region: "test",
		Host:   m.Address(),
	}

	w.Header().Set("content-type", "application/json")
	enc := json.NewEncoder(w)
	enc.Encode(&rr)
}

func sendFault(w http.ResponseWriter, errorCode int, fault, code string) {
	w.Header().Set("content-type", "application/json")
	w.WriteHeader(errorCode)
	f := &common.APIFaultMessage{
		Fault: common.APIFault{
			FaultString: fault,
			Detail: common.APIFaultDetail{
				ErrorCode: code,
			},
		},
	}

	enc := json.NewEncoder(w)
	enc.Encode(f)
}

func makeJWT1() jwt.JWT {
	now := time.Now()
	c := jws.Claims{}
	c.SetIssuedAt(now)
	c.SetNotBefore(now)
	c.Set("audience", "microgateway")
	c.Set("jti", "52137037-6ce1-426e-a255-e471f94854e5")
	c.Set("iss", "https://mock.foo.net/verifyApiKey")
	c.Set("client_id", ValidAPIKey1)
	c.Set("application_name", "TestApp1")
	c.Set("api_product_list", []string{
		"TestProduct1",
	})

	return jws.NewJWT(c, crypto.SigningMethodRS256)
}

func makeJWT2() jwt.JWT {
	now := time.Now()
	c := jws.Claims{}
	c.SetIssuedAt(now)
	c.SetNotBefore(now)
	c.Set("audience", "microgateway")
	c.Set("jti", "52137037-6ce1-426e-a255-e471f94854e5")
	c.Set("iss", "https://mock.foo.net/verifyApiKey")
	c.Set("client_id", ValidAPIKeyNoProducts)
	c.Set("application_name", "TestApp2")
	c.Set("api_product_list", []string{
		"UnknownProduct1",
	})

	return jws.NewJWT(c, crypto.SigningMethodRS256)
}
