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

import (
	"net/http"

	"github.com/apid/apid-core/util"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	mathrand "math/rand"
	"sync/atomic"
	"time"
)

const (
	bundleTestUrl       = "http://127.0.0.1:9000"
	dummySignedEndpoint = "/dummyblob/{blobId}"
)

var _ = Describe("api", func() {
	// var testCount int
	var testBundleMan *bundleManager
	var dummyDbMan *dummyDbManager
	var dummyApiMan *dummyApiManager
	var blobServer *dummyBlobServer

	var _ = BeforeEach(func() {
		// testCount += 1
		concurrentDownloads := 5
		downloadQueueSize := 5

		// init test blob server
		if blobServer == nil {
			blobServer = &dummyBlobServer{
				serverEndpoint: blobStoreUri,
				signedEndpoint: dummySignedEndpoint,
				signedTimeout:  new(int32),
				blobTimeout:    new(int32),
				resetTimeout:   true,
			}
			blobServer.start()
		}

		// init dummy db manager
		dummyDbMan = &dummyDbManager{
			fileResponse: make(chan string),
		}

		// init dummy api manager
		dummyApiMan = &dummyApiManager{
			notifyChan: make(chan bool, 1),
			initCalled: make(chan bool),
		}

		// init bundle manager
		testBundleMan = &bundleManager{
			blobServerUrl:         bundleTestUrl,
			dbMan:                 dummyDbMan,
			apiMan:                dummyApiMan,
			concurrentDownloads:   concurrentDownloads,
			markConfigFailedAfter: 5 * time.Second,
			bundleRetryDelay:      time.Second,
			bundleCleanupDelay:    5 * time.Second,
			downloadQueue:         make(chan *DownloadRequest, downloadQueueSize),
			isClosed:              new(int32),
			client: &http.Client{
				Timeout: time.Second,
				Transport: &http.Transport{
					MaxIdleConnsPerHost: 10,
				},
			},
		}
		testBundleMan.initializeBundleDownloading()
		time.Sleep(100 * time.Millisecond)
	})

	var _ = AfterEach(func() {
		testBundleMan.Close()
		testBundleMan = nil
		dummyDbMan = nil
		dummyApiMan = nil
	})

	Context("download blobs", func() {

		It("should download blob according to id", func() {
			// download blob
			id := util.GenerateUUID()
			testBundleMan.enqueueRequest(testBundleMan.makeDownloadRequest(id, nil))
			received := <-dummyDbMan.fileResponse
			Expect(received).Should(Equal(id))
		})

		It("should timeout connection and retry", func() {
			// setup timeout
			atomic.StoreInt32(blobServer.signedTimeout, 1)
			atomic.StoreInt32(blobServer.blobTimeout, 1)
			testBundleMan.client.Timeout = 500 * time.Millisecond
			testBundleMan.bundleRetryDelay = 50 * time.Millisecond

			// download blobs
			id := util.GenerateUUID()
			testBundleMan.enqueueRequest(testBundleMan.makeDownloadRequest(id, nil))
			received := <-dummyDbMan.fileResponse
			Expect(received).Should(Equal(id))

		}, 4)

		It("should mark as failure according to markConfigFailedAfter", func() {
			// setup timeout
			atomic.StoreInt32(blobServer.signedTimeout, 1)
			atomic.StoreInt32(blobServer.blobTimeout, 1)
			testBundleMan.client.Timeout = 100 * time.Millisecond
			testBundleMan.bundleRetryDelay = 100 * time.Millisecond
			testBundleMan.markConfigFailedAfter = 200 * time.Millisecond

			// download blobs
			id := util.GenerateUUID()
			req := testBundleMan.makeDownloadRequest(id, nil)
			Expect(req.markFailedAt.After(time.Now())).Should(BeTrue())
			testBundleMan.enqueueRequest(req)

			// should fail
			time.Sleep(time.Second)
			Expect(req.markFailedAt.IsZero()).Should(BeTrue())
		}, 4)

		It("should call callback func after a round of download attempts", func() {
			// download blobs
			var ids []string
			num := 1 + mathrand.Intn(5)
			for i := 0; i < num; i++ {
				ids = append(ids, util.GenerateUUID())
			}
			finishChan := make(chan int)
			testBundleMan.downloadBlobsWithCallback(ids, func() {
				finishChan <- 1
			})
			for i := 0; i < num; i++ {
				<-dummyDbMan.fileResponse
			}
			<-finishChan
			// if there's no blob
			testBundleMan.downloadBlobsWithCallback(nil, func() {
				finishChan <- 1
			})
			<-finishChan
		}, 1)
	})

	Context("download blobs for changelist", func() {
		It("should download blobs for changelist", func() {
			//setup test data
			count := mathrand.Intn(10) + 1
			configs := make([]*Configuration, count)
			for i := 0; i < count; i++ {
				conf := makeTestDeployment()
				conf.BlobID = util.GenerateUUID()
				conf.BlobResourceID = util.GenerateUUID()
				configs[i] = conf
			}

			// should download blobs for changelist
			testBundleMan.downloadBlobsWithCallback(extractBlobsToDownload(configs), dummyApiMan.notifyNewChange)
			for i := 0; i < 2*count; i++ {
				<-dummyDbMan.fileResponse
			}

			// should notify after 1st download attempt
			<-dummyApiMan.notifyChan
		})

		It("should notify after 1st download attempt unless failure", func() {
			//setup test data
			count := mathrand.Intn(10) + 1
			configs := make([]*Configuration, count)
			for i := 0; i < count; i++ {
				conf := makeTestDeployment()
				conf.BlobID = util.GenerateUUID()
				conf.BlobResourceID = util.GenerateUUID()
				configs[i] = conf
			}

			// setup timeout
			atomic.StoreInt32(blobServer.signedTimeout, 1)
			atomic.StoreInt32(blobServer.blobTimeout, 1)
			testBundleMan.client.Timeout = 500 * time.Millisecond
			testBundleMan.bundleRetryDelay = 50 * time.Millisecond

			// should download blobs for changelist
			testBundleMan.downloadBlobsWithCallback(extractBlobsToDownload(configs), dummyApiMan.notifyNewChange)

			// should notify after 1st download attempt
			<-dummyApiMan.notifyChan

			//should retry download
			for i := 0; i < 2*count; i++ {
				<-dummyDbMan.fileResponse
			}
		})

	})

})
