/*
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"
	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:           "First",
			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",
		},
	}

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

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

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
	}

	if request.Key != ValidAPIKey1 {
		// 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
	}

	jwt := makeJWT1()
	bod, err := jwt.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)
}
