/*
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 (
	"bytes"
	"compress/gzip"
	"crypto/x509"
	"encoding/json"
	"encoding/pem"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"testing"
	"time"

	"io"

	"github.com/SermoDigital/jose/jws"
	"github.com/apid/istioApigeeAdapter/common"
)

var testMockServer *MockServer

func TestMain(m *testing.M) {
	var err error
	testMockServer, err = StartMockServer(0)
	if err != nil {
		panic(err.Error())
	}

	result := m.Run()
	testMockServer.Stop()
	os.Exit(result)
}

func TestServerSanity(t *testing.T) {
	if mockKeyPEM == nil {
		t.Fatal("Expected mock key to be generated")
	}
	if mockCertPEM == nil {
		t.Fatal("Expected mock cert to be generated")
	}
}

func TestPublicKey(t *testing.T) {
	resp, err := http.Get(fmt.Sprintf("http://%s/publicKey", testMockServer.Address()))
	if err != nil {
		t.Fatalf("Network error: %s", err)
	}
	defer resp.Body.Close()
	if resp.StatusCode != 200 {
		t.Fatalf("Got HTTP status code %d", resp.StatusCode)
	}

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		t.Fatalf("Error reading body: %s", err)
	}
	pb, _ := pem.Decode(body)
	if pb == nil {
		t.Fatalf("Failed decoding public key body \"%s\"", string(body))
	}
	if pb.Type != "CERTIFICATE" {
		t.Fatalf("Got back invalid PEM type %s", pb.Type)
	}

	cert, err := x509.ParseCertificate(pb.Bytes)
	if err != nil {
		t.Fatalf("Error decoding certificate: %s", err)
	}
	if cert.Subject.CommonName != "mockserver" {
		t.Fatalf("Common name does not match \"mockserver\": \"%s\"", cert.Subject.CommonName)
	}
}

func TestProducts(t *testing.T) {
	resp, err := http.Get(fmt.Sprintf("http://%s/products", testMockServer.Address()))
	if err != nil {
		t.Fatalf("Network error: %s", err)
	}
	defer resp.Body.Close()
	if resp.StatusCode != 200 {
		t.Fatalf("Got HTTP status code %d", resp.StatusCode)
	}
	if resp.Header.Get("content-type") != "application/json" {
		t.Fatalf("Invalid content typs %s", resp.Header.Get("content-type"))
	}

	dec := json.NewDecoder(resp.Body)
	var products []common.APIProduct
	err = dec.Decode(&products)
	if err != nil {
		t.Fatalf("Error decoding response json: %s", err)
	}
}

func TestAPIKeyWrongFormat(t *testing.T) {
	req := common.VerifyAPIKeyRequest{}
	requestBod, _ := json.Marshal(&req)
	resp, err := http.DefaultClient.Post(
		fmt.Sprintf("http://%s/verifyApiKey", testMockServer.Address()),
		"text/plain",
		bytes.NewBuffer(requestBod))
	if err != nil {
		t.Fatalf("Network error: %s", err)
	}
	defer resp.Body.Close()
	if resp.StatusCode != 404 {
		t.Fatalf("Got HTTP status code %d -- expected 404", resp.StatusCode)
	}
}

func TestAPIKeyNotJSON(t *testing.T) {
	resp, err := http.DefaultClient.Post(
		fmt.Sprintf("http://%s/verifyApiKey", testMockServer.Address()),
		"application/json",
		bytes.NewBuffer([]byte("Hello!")))
	if err != nil {
		t.Fatalf("Network error: %s", err)
	}
	defer resp.Body.Close()
	if resp.StatusCode != 500 {
		t.Fatalf("Got HTTP status code %d -- expected 500", resp.StatusCode)
	}
}

func TestAPIKeyNoKey(t *testing.T) {
	req := common.VerifyAPIKeyRequest{}
	requestBod, _ := json.Marshal(&req)
	resp, err := http.DefaultClient.Post(
		fmt.Sprintf("http://%s/verifyApiKey", testMockServer.Address()),
		"application/json",
		bytes.NewBuffer(requestBod))
	if err != nil {
		t.Fatalf("Network error: %s", err)
	}
	defer resp.Body.Close()
	if resp.StatusCode != 401 {
		t.Fatalf("Got HTTP status code %d -- expected 401", resp.StatusCode)
	}
}

func TestAPIKeyBadKey(t *testing.T) {
	req := common.VerifyAPIKeyRequest{
		Key: "foobar",
	}
	requestBod, _ := json.Marshal(&req)
	resp, err := http.DefaultClient.Post(
		fmt.Sprintf("http://%s/verifyApiKey", testMockServer.Address()),
		"application/json",
		bytes.NewBuffer(requestBod))
	if err != nil {
		t.Fatalf("Network error: %s", err)
	}
	defer resp.Body.Close()
	if resp.StatusCode != 401 {
		t.Fatalf("Got HTTP status code %d -- expected 401", resp.StatusCode)
	}
}

func TestAPIKeySuccess(t *testing.T) {
	req := common.VerifyAPIKeyRequest{
		Key: ValidAPIKey1,
	}
	requestBod, _ := json.Marshal(&req)
	resp, err := http.DefaultClient.Post(
		fmt.Sprintf("http://%s/verifyApiKey", testMockServer.Address()),
		"application/json",
		bytes.NewBuffer(requestBod))
	if err != nil {
		t.Fatalf("Network error: %s", err)
	}
	defer resp.Body.Close()
	if resp.StatusCode != 200 {
		t.Fatalf("Got HTTP status code %d -- expected 200", resp.StatusCode)
	}

	var respBody common.VerifyAPIKeyResponse
	dec := json.NewDecoder(resp.Body)
	err = dec.Decode(&respBody)
	if err != nil {
		t.Fatalf("Error reading JSON response: %s", err)
	}

	_, err = jws.ParseJWT([]byte(respBody.Token))
	if err != nil {
		t.Fatalf("Error parsing JWT: %s", err)
	}
}

func TestAxPublishBadJSON(t *testing.T) {
	resp, err := sendAnalytics([]byte("NOTJSON"), "application/json",
		ValidPublishKey, ValidPublishSecret, false)
	if err != nil {
		t.Fatalf("Network error sending request: %s", err)
	}
	defer resp.Body.Close()
	if resp.StatusCode != 500 {
		t.Fatalf("Got status code %d and expected 500", resp.StatusCode)
	}
}

func TestAxPublishNotJSON(t *testing.T) {
	resp, err := sendAnalytics([]byte("{}"), "text/plain",
		ValidPublishKey, ValidPublishSecret, false)
	if err != nil {
		t.Fatalf("Network error sending request: %s", err)
	}
	defer resp.Body.Close()
	if resp.StatusCode != 200 {
		t.Fatalf("Got status code %d and expected 200", resp.StatusCode)
	}

	var respBody common.AnalyticsResponse
	dec := json.NewDecoder(resp.Body)
	err = dec.Decode(&respBody)
	if err != nil {
		t.Fatalf("Error reading JSON response: %s", err)
	}

	if respBody.Accepted != 0 {
		t.Fatalf("%d records were accepted", respBody.Accepted)
	}
	if respBody.Rejected != 1 {
		t.Fatalf("%d records were rejected", respBody.Rejected)
	}
}

func TestAxPublishEmpty(t *testing.T) {
	resp, err := sendAnalytics([]byte("{}"), "application/json",
		ValidPublishKey, ValidPublishSecret, false)
	if err != nil {
		t.Fatalf("Network error sending request: %s", err)
	}
	defer resp.Body.Close()
	if resp.StatusCode != 200 {
		t.Fatalf("Got status code %d and expected 200", resp.StatusCode)
	}

	var respBody common.AnalyticsResponse
	dec := json.NewDecoder(resp.Body)
	err = dec.Decode(&respBody)
	if err != nil {
		t.Fatalf("Error reading JSON response: %s", err)
	}

	if respBody.Accepted != 0 {
		t.Fatalf("%d records were accepted", respBody.Accepted)
	}
	if respBody.Rejected != 0 {
		t.Fatalf("%d records were rejected", respBody.Rejected)
	}
}

func TestAxPublishWrongUser(t *testing.T) {
	resp, err := sendAnalytics([]byte("{}"), "application/json",
		"NOTVALID", ValidPublishSecret, false)
	if err != nil {
		t.Fatalf("Network error sending request: %s", err)
	}
	defer resp.Body.Close()
	if resp.StatusCode != 401 {
		t.Fatalf("Got status code %d and expected 401", resp.StatusCode)
	}
}

func TestAxPublishWrongPW(t *testing.T) {
	resp, err := sendAnalytics([]byte("{}"), "application/json",
		ValidPublishKey, "NOPE", false)
	if err != nil {
		t.Fatalf("Network error sending request: %s", err)
	}
	defer resp.Body.Close()
	if resp.StatusCode != 401 {
		t.Fatalf("Got status code %d and expected 401", resp.StatusCode)
	}
}

func TestAxPublishNoAuth(t *testing.T) {
	resp, err := http.Post(
		fmt.Sprintf("http://%s/edgemicro/axpublisher/organization/foo/environment/test", testMockServer.Address()),
		"application/json", bytes.NewReader([]byte("{}")))
	if err != nil {
		t.Fatalf("Network error sending request: %s", err)
	}
	defer resp.Body.Close()
	if resp.StatusCode != 401 {
		t.Fatalf("Got status code %d and expected 401", resp.StatusCode)
	}
}

func TestAxPublishCompressed(t *testing.T) {
	requestBod, err := json.Marshal(makeRequest(10))
	if err != nil {
		t.Fatalf("Error making JSON: %s", err)
	}
	resp, err := sendAnalytics(requestBod, "application/json",
		ValidPublishKey, ValidPublishSecret, true)
	if err != nil {
		t.Fatalf("Network error sending request: %s", err)
	}
	defer resp.Body.Close()
	if resp.StatusCode != 200 {
		t.Fatalf("Got status code %d", resp.StatusCode)
	}

	var respBody common.AnalyticsResponse
	dec := json.NewDecoder(resp.Body)
	err = dec.Decode(&respBody)
	if err != nil {
		t.Fatalf("Error reading JSON response: %s", err)
	}

	if respBody.Accepted != 10 {
		t.Fatalf("Only %d record accepted", respBody.Accepted)
	}
	if respBody.Rejected != 0 {
		t.Fatalf("%d records were rejected", respBody.Rejected)
	}
}

func sendAnalytics(body []byte, contentType, user, pw string, compress bool) (*http.Response, error) {
	var bod io.Reader

	if compress {
		bb := &bytes.Buffer{}
		zw := gzip.NewWriter(bb)
		zw.Write(body)
		zw.Close()
		bod = bb
	} else {
		bod = bytes.NewBuffer(body)
	}

	req, err := http.NewRequest(
		"POST",
		fmt.Sprintf("http://%s/edgemicro/axpublisher/organization/foo/environment/test", testMockServer.Address()),
		bod)
	if err != nil {
		return nil, err
	}
	req.Header.Set("content-type", contentType)
	if compress {
		req.Header.Set("content-encoding", "gzip")
	}
	req.SetBasicAuth(user, pw)
	return http.DefaultClient.Do(req)
}

func TestRegionCheck(t *testing.T) {
	req, err := http.NewRequest(
		"GET",
		fmt.Sprintf("http://%s/edgemicro/region/organization/foo/environment/test", testMockServer.Address()),
		nil)
	if err != nil {
		t.Fatal("Can't make request")
	}
	req.SetBasicAuth(ValidPublishKey, ValidPublishSecret)
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		t.Fatalf("Network error sending request: %s", err)
	}
	defer resp.Body.Close()
	if resp.StatusCode != 200 {
		t.Fatalf("Got status code %d", resp.StatusCode)
	}

	var rr common.RegionResponse
	dec := json.NewDecoder(resp.Body)
	err = dec.Decode(&rr)
	if err != nil {
		t.Fatalf("Error reading JSON response: %s", err)
	}

	if rr.Host != testMockServer.Address() {
		t.Fatalf("Invalid host response %s", rr.Host)
	}
}

func TestRegionCheckNoAuth(t *testing.T) {
	req, err := http.NewRequest(
		"GET",
		fmt.Sprintf("http://%s/edgemicro/region/organization/foo/environment/test", testMockServer.Address()),
		nil)
	if err != nil {
		t.Fatal("Can't make request")
	}
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		t.Fatalf("Network error sending request: %s", err)
	}
	defer resp.Body.Close()
	if resp.StatusCode != 401 {
		t.Fatalf("Got status code %d", resp.StatusCode)
	}
}

func makeRequest(numRecords int) *common.AnalyticsRequest {
	var recs []common.AnalyticsRecord

	for i := 0; i < numRecords; i++ {
		now := time.Now().UnixNano() / 1000000
		nr := common.AnalyticsRecord{
			ClientReceivedStartTimestamp: now,
			ClientReceivedEndTimestamp:   now + 1,
			ClientSentStartTimestamp:     now + 10,
			ClientSentEndTimestamp:       now + 11,
			RecordType:                   "APIAnalytics",
			APIProxy:                     "helloworld",
			RequestURI:                   "http://hello/world",
			RequestPath:                  "/world",
			RequestVerb:                  "GET",
			ClientIP:                     "192.168.201.100",
			UserAgent:                    "Testing",
			APIProxyRevision:             1,
			ResponseStatusCode:           200,
		}
		recs = append(recs, nr)
	}

	return &common.AnalyticsRequest{
		Records: recs,
	}
}
