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

import (
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	"github.com/30x/apid-core"
	"github.com/30x/apid-core/factory"
	"io/ioutil"
	//"net/http"
	"net/http/httptest"
	"os"
	"testing"
)

var (
	testTempDir string
	testServer  *httptest.Server
)

var _ = BeforeSuite(func() {
	apid.Initialize(factory.DefaultServicesFactory())

	config := apid.Config()

	var err error
	testTempDir, err = ioutil.TempDir("", "api_test")
	Expect(err).NotTo(HaveOccurred())

	config.Set("data_path", testTempDir)

	apid.InitializePlugins("")

	db, err := apid.Data().DB()
	Expect(err).NotTo(HaveOccurred())
	//setDB(db)
	//createTables(db)
	//createApidClusterTables(db)
	//addScopes(db)
	//testServer = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
	//	if req.URL.Path == apiPath {
	//		handleRequest(w, req)
	//	}
	//}))

	createTestData(db)
})

var _ = AfterSuite(func() {
	apid.Events().Close()
	if testServer != nil {
		testServer.Close()
	}
	os.RemoveAll(testTempDir)
})

func TestVerifyAPIKey(t *testing.T) {
	RegisterFailHandler(Fail)
	RunSpecs(t, "VerifyAPIKey Suite")
}

func createTestData(db apid.DB) {
	txn, err := db.Begin()
	Expect(err).ShouldNot(HaveOccurred())
	// api products
	for i := 0; i < 10; i++ {
		generateTestApiProduct(i, txn)
	}
	// developers
	for i := 0; i < 10; i++ {
		generateTestDeveloper(i, txn)
	}

	// application
	var j, k int
	for i := 0; i < 10; i++ {
		for j = k; j < 10+k; j++ {
			generateTestApp(j, i, txn)
		}
		k = j
	}
	// app credentials
	for i := 0; i < 10; i++ {
		generateTestAppCreds(i, txn)
	}
	// api product mapper
	for i := 0; i < 10; i++ {
		generateTestApiProductMapper(i, txn)
	}

	// Following are data for company
	// api products
	for i := 100; i < 110; i++ {
		generateTestApiProduct(i, txn)
	}

	// companies
	for i := 100; i < 110; i++ {
		generateTestCompany(i, txn)
	}

	// company developers
	for i := 100; i < 110; i++ {
		generateTestCompanyDeveloper(i, txn)
	}

	// application
	k = 100
	for i := 100; i < 110; i++ {
		for j = k; j < 100+k; j++ {
			generateTestAppCompany(j, i, txn)
		}
		k = j
	}
	// app credentials
	for i := 100; i < 110; i++ {
		generateTestAppCreds(i, txn)
	}
	// api product mapper
	for i := 100; i < 110; i++ {
		generateTestApiProductMapper(i, txn)
	}

	txn.Commit()
	var count int64
	db.QueryRow("select count(*) from EDGEX_DATA_SCOPE").Scan(&count)
	log.Info("Found ", count)
}
