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

import (
	"encoding/json"
	"github.com/30x/apid-core"
	"github.com/30x/apid-core/factory"
	_ "github.com/30x/apidApigeeSync"
	"github.com/apigee-labs/transicator/common"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"net/http/httptest"
	"os"
	"testing"
	"time"
)

var (
	services            apid.Services
	log                 apid.LogService
	dataService         apid.DataService
	config              apid.ConfigService
	pgUrl               string
	pgManager           *ManagementPg
	clusterIdFromConfig string
)

/*
 * This test suite acts like a dummy plugin. It listens to events emitted by
 * apidApigeeSync and runs tests.
 */
var _ = BeforeSuite(func() {
	defer GinkgoRecover()
	//hostname := "http://" + os.Getenv("APIGEE_SYNC_DOCKER_IP")
	pgUrl = os.Getenv("APIGEE_SYNC_DOCKER_PG_URL") + "?sslmode=disable"
	os.Setenv("APID_CONFIG_FILE", "./apid_config.yaml")

	apid.Initialize(factory.DefaultServicesFactory())
	config = apid.Config()

	localStorage := config.GetString(configLocalStoragePath)
	err := os.RemoveAll(localStorage)
	Expect(err).Should(Succeed())
	err = os.MkdirAll(localStorage, 0700)
	Expect(err).Should(Succeed())

	// init pg driver and data
	pgManager, err = InitDb(pgUrl)
	Expect(err).Should(Succeed())
	initPgData()

	// Auth Server
	config.Set(configName, "dockerIT")
	config.Set(configConsumerKey, "dummyKey")
	config.Set(configConsumerSecret, "dummySecret")
	testServer := initDummyAuthServer()

	initDone := make(chan bool)
	handler := &waitSnapshotHandler{initDone}

	// hang until snapshot received
	apid.Events().Listen(ApigeeSyncEventSelector, handler)

	config.Set(configProxyServerBaseURI, testServer.URL)

	// init plugin
	apid.RegisterPlugin(initPlugin)
	apid.InitializePlugins("dockerTest")

	<-initDone
}, 5)

var _ = AfterSuite(func() {
	err := pgManager.CleanupAll()
	Expect(err).Should(Succeed())
})

var _ = Describe("dockerIT", func() {

	/*
	 * Isolation between tests is not perfect.
	 * If in a test you listen to any event, please make sure you stop listening to it,
	 * and don't let it mess up later tests.
	 */
	Context("Generic Replication", func() {
		var _ = BeforeEach(func() {

		})

		var _ = AfterEach(func() {
			err := pgManager.CleanupTest()
			Expect(err).Should(Succeed())
		})

		It("should succesfully download new table from pg", func(done Done) {
			tableName := "docker_test_a"
			targetTablename := "edgex_" + tableName
			handler := &newTableHandler{
				targetTablename: targetTablename,
				done:            done,
			}

			apid.Events().Listen(ApigeeSyncEventSelector, handler)
			createTestTable(tableName)

		}, 1)

		It("should get data according to data scope", func(done Done) {
			tableName := "docker_test_b"
			targetTablename := "edgex_" + tableName
			handler := &newTableHandler{
				targetTablename: targetTablename,
				done:            done,
			}

			apid.Events().Listen(ApigeeSyncEventSelector, handler)
			createTestTableWithData(tableName)

		}, 1)
	})
})

func createTestTable(tableName string) {
	tx, err := pgManager.BeginTransaction()
	Expect(err).Should(Succeed())
	defer tx.Rollback()
	_, err = tx.Exec("CREATE TABLE edgex." + tableName + " (id varchar primary key, val integer, _change_selector varchar);")
	Expect(err).Should(Succeed())
	_, err = tx.Exec("ALTER TABLE edgex." + tableName + " replica identity full;")
	Expect(err).Should(Succeed())
	tx.Commit()
}

func createTestTableWithData(tableName string) {
	tx, err := pgManager.BeginTransaction()
	Expect(err).Should(Succeed())
	defer tx.Rollback()
	_, err = tx.Exec("CREATE TABLE edgex." + tableName + " (id varchar primary key, val integer, _change_selector varchar);")
	Expect(err).Should(Succeed())
	_, err = tx.Exec("ALTER TABLE edgex." + tableName + " replica identity full;")
	Expect(err).Should(Succeed())
	_, err = tx.Exec("INSERT INTO edgex." + tableName + " values ('one', 1, 'foo');")
	Expect(err).Should(Succeed())
	_, err = tx.Exec("INSERT INTO edgex." + tableName + " values ('two', 2, 'bar');")
	Expect(err).Should(Succeed())
	_, err = tx.Exec("INSERT INTO edgex." + tableName + " values ('three', 3, '" + clusterIdFromConfig + "');")
	Expect(err).Should(Succeed())
	tx.Commit()
}

func dropTestTable(targetTableName string, sqliteDb apid.DB) {
	tx, err := pgManager.BeginTransaction()
	Expect(err).Should(Succeed())
	_, err = tx.Exec("DROP TABLE IF EXISTS edgex." + targetTableName + ";")
	Expect(err).Should(Succeed())
}

func initDummyAuthServer() (testServer *httptest.Server) {
	testRouter := apid.API().Router()
	testServer = httptest.NewServer(testRouter)
	mockAuthServer := &MockAuthServer{}
	mockAuthServer.Start(testRouter)
	return
}

func initPlugin(s apid.Services) (apid.PluginData, error) {
	services = s
	log = services.Log().ForModule(pluginName)
	dataService = services.Data()

	var pluginData = apid.PluginData{
		Name:    pluginName,
		Version: "0.0.1",
		ExtraData: map[string]interface{}{
			"schemaVersion": "0.0.1",
		},
	}

	log.Info(pluginName + " initialized.")
	return pluginData, nil
}

func initPgData() {
	clusterIdFromConfig = config.GetString(configApidClusterId) //"4c6bb536-0d64-43ca-abae-17c08f1a7e58"
	clusterId := clusterIdFromConfig
	scopeId := "ae418890-2c22-4c6a-b218-69e261034b96"
	deploymentId := "633af126-ee79-4a53-bef7-7ba30da8aad6"
	bundleConfigId := "613ce223-6c73-43f4-932c-3c69b0c7c65d"
	bundleConfigName := "good"
	bundleUri := "https://gist.github.com/alexkhimich/843cf70ffd6a8b4d44442876ba0487b7/archive/d74360596ff9a4320775d590b3f5a91bdcdf61d2.zip"
	t := time.Now()

	cluster := &apidClusterRow{
		id:             clusterId,
		name:           "apidcA",
		description:    "desc",
		appName:        "UOA",
		created:        t,
		createdBy:      testInitUser,
		updated:        t,
		updatedBy:      testInitUser,
		changeSelector: clusterId,
	}

	ds := &dataScopeRow{
		id:             scopeId,
		clusterId:      clusterId,
		scope:          "abc1",
		org:            "org1",
		env:            "env1",
		created:        t,
		createdBy:      testInitUser,
		updated:        t,
		updatedBy:      testInitUser,
		changeSelector: clusterId,
	}

	bf := bundleConfigData{
		Id:        bundleConfigId,
		Created:   t.Format(time.RFC3339),
		CreatedBy: testInitUser,
		Updated:   t.Format(time.RFC3339),
		UpdatedBy: testInitUser,
		Name:      bundleConfigName,
		Uri:       bundleUri,
	}

	jsonBytes, err := json.Marshal(bf)
	Expect(err).Should(Succeed())

	bfr := &bundleConfigRow{
		id:           bf.Id,
		scopeId:      scopeId,
		name:         bf.Name,
		uri:          bf.Uri,
		checksumType: "",
		checksum:     "",
		created:      t,
		createdBy:    bf.CreatedBy,
		updated:      t,
		updatedBy:    bf.UpdatedBy,
	}

	d := &deploymentRow{
		id:               deploymentId,
		configId:         bundleConfigId,
		clusterId:        clusterId,
		scopeId:          scopeId,
		bundleConfigName: bundleConfigName,
		bundleConfigJson: string(jsonBytes),
		configJson:       "{}",
		created:          t,
		createdBy:        testInitUser,
		updated:          t,
		updatedBy:        testInitUser,
		changeSelector:   clusterId,
	}

	tx, err := pgManager.BeginTransaction()
	Expect(err).Should(Succeed())
	defer tx.Rollback()
	err = pgManager.InsertApidCluster(tx, cluster)
	Expect(err).Should(Succeed())
	err = pgManager.InsertDataScope(tx, ds)
	Expect(err).Should(Succeed())
	err = pgManager.InsertBundleConfig(tx, bfr)
	Expect(err).Should(Succeed())
	err = pgManager.InsertDeployment(tx, d)
	Expect(err).Should(Succeed())
	err = tx.Commit()
	Expect(err).Should(Succeed())
}

type waitSnapshotHandler struct {
	initDone chan bool
}

func (w *waitSnapshotHandler) Handle(event apid.Event) {
	if _, ok := event.(*common.Snapshot); ok {
		apid.Events().StopListening(ApigeeSyncEventSelector, w)
		w.initDone <- true
	}
}

type newTableHandler struct {
	targetTablename string
	done            Done
}

func (n *newTableHandler) Handle(event apid.Event) {
	if s, ok := event.(*common.Snapshot); ok {
		sqliteDb, err := dataService.DBVersion(s.SnapshotInfo)
		Expect(err).Should(Succeed())
		Expect(verifyTestTableExist(n.targetTablename, sqliteDb)).To(BeTrue())
		apid.Events().StopListening(ApigeeSyncEventSelector, n)
		close(n.done)
	}
}

func verifyTestTableExist(targetTableName string, sqliteDb apid.DB) bool {
	rows, err := sqliteDb.Query("SELECT DISTINCT tableName FROM _transicator_tables;")
	Expect(err).Should(Succeed())
	defer rows.Close()
	for rows.Next() {
		var tableName string
		err = rows.Scan(&tableName)
		Expect(err).Should(Succeed())

		if tableName == targetTableName {
			return true
		}
	}
	return false
}

type newTableScopeHandler struct {
	targetTablename string
	done            Done
}

func (n *newTableScopeHandler) Handle(event apid.Event) {
	if s, ok := event.(*common.Snapshot); ok {
		sqliteDb, err := dataService.DBVersion(s.SnapshotInfo)
		Expect(err).Should(Succeed())
		verifyTestTableData(n.targetTablename, sqliteDb)
		apid.Events().StopListening(ApigeeSyncEventSelector, n)
		close(n.done)
	}
}

func verifyTestTableData(targetTableName string, sqliteDb apid.DB) {
	rows, err := sqliteDb.Query("SELECT id FROM " + targetTableName + ";")
	Expect(err).Should(Succeed())
	defer rows.Close()
	count := 0
	for rows.Next() {
		var id string
		err = rows.Scan(&id)
		Expect(err).Should(Succeed())
		Expect(id).To(Equal("three"))
		count += 1
	}
	Expect(count).To(Equal(1))
}

func TestDockerApigeeSync(t *testing.T) {
	RegisterFailHandler(Fail)
	RunSpecs(t, "ApigeeSync Docker Suite")
}
