/*
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 (
	"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("/axpublisher/organization/:org/environment/:env", ms.publishAnalytics)

	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 {
		sendFault(w, 404,
			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
	defer r.Body.Close()
	dec := json.NewDecoder(r.Body)
	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 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)
}
