/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 integrationtest_test

import (
	"bytes"
	"encoding/json"
	"io/ioutil"
	"math/rand"
	"net/http"
	"strconv"
	"strings"
	"time"

	. "github.com/apache/servicecomb-service-center/integration"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/widuu/gojson"
)

var _ = Describe("MicroService Api Test", func() {
	var serviceName = "integrationtestInstances"
	var serviceId = ""
	var serviceAppId = "integrationtestAppIdInstance"
	var serviceVersion = "0.0.2"
	Context("Tesing MicroService Tags API's", func() {
		BeforeEach(func() {
			schema := []string{"testSchema"}
			properties := map[string]string{"attr1": "aa"}
			servicemap := map[string]interface{}{
				"serviceName": serviceName + strconv.Itoa(rand.Int()),
				"appId":       serviceAppId,
				"version":     serviceVersion,
				"description": "examples",
				"level":       "FRONT",
				"schemas":     schema,
				"status":      "UP",
				"properties":  properties,
			}
			bodyParams := map[string]interface{}{
				"service": servicemap,
			}
			body, _ := json.Marshal(bodyParams)
			bodyBuf := bytes.NewReader(body)
			req, _ := http.NewRequest(POST, SCURL+REGISTERMICROSERVICE, bodyBuf)
			req.Header.Set("X-Domain-Name", "default")
			resp, err := scclient.Do(req)
			Expect(err).To(BeNil())
			defer resp.Body.Close()

			// Validate the service creation
			Expect(resp.StatusCode).To(Equal(http.StatusOK))
			respbody, _ := ioutil.ReadAll(resp.Body)
			serviceId = gojson.Json(string(respbody)).Get("serviceId").Tostring()
			Expect(len(serviceId)).Should(BeNumerically("==", LengthUUID))
		})

		AfterEach(func() {
			if serviceId != "" {
				url := strings.Replace(UNREGISTERMICROSERVICE, ":serviceId", serviceId, 1)
				req, _ := http.NewRequest(DELETE, SCURL+url, nil)
				req.Header.Set("X-Domain-Name", "default")
				resp, _ := scclient.Do(req)
				Expect(resp.StatusCode).To(Equal(http.StatusOK))
			}

		})

		By("Create Micro-Service Tag API", func() {
			It("Create MicroService tags", func() {
				tags := map[string]interface{}{
					"testkey": "testValue",
				}

				bodyParams := map[string]interface{}{
					"tags": tags,
				}
				url := strings.Replace(ADDTAGE, ":serviceId", serviceId, 1)
				body, _ := json.Marshal(bodyParams)
				bodyBuf := bytes.NewReader(body)
				req, _ := http.NewRequest(POST, SCURL+url, bodyBuf)
				req.Header.Set("X-Domain-Name", "default")
				resp, err := scclient.Do(req)
				Expect(err).To(BeNil())
				defer resp.Body.Close()

				Expect(resp.StatusCode).To(Equal(http.StatusOK))
			})

			It("Create MicroService tags with empty collections, should be pass", func() {
				bodyParams := map[string]interface{}{}
				url := strings.Replace(ADDTAGE, ":serviceId", serviceId, 1)
				body, _ := json.Marshal(bodyParams)
				bodyBuf := bytes.NewReader(body)
				req, _ := http.NewRequest(POST, SCURL+url, bodyBuf)
				req.Header.Set("X-Domain-Name", "default")
				resp, err := scclient.Do(req)
				Expect(err).To(BeNil())
				defer resp.Body.Close()

				Expect(resp.StatusCode).To(Equal(http.StatusOK))

				tags := map[string]interface{}{}
				bodyParams = map[string]interface{}{
					"tags": tags,
				}
				url = strings.Replace(ADDTAGE, ":serviceId", serviceId, 1)
				body, _ = json.Marshal(bodyParams)
				bodyBuf = bytes.NewReader(body)
				req, _ = http.NewRequest(POST, SCURL+url, bodyBuf)
				req.Header.Set("X-Domain-Name", "default")
				resp, err = scclient.Do(req)
				Expect(err).To(BeNil())
				defer resp.Body.Close()

				Expect(resp.StatusCode).To(Equal(http.StatusOK))
			})

			It("Create MicroService tags with invalid serviceID", func() {
				tags := map[string]interface{}{
					"testkey": "testValue",
				}
				bodyParams := map[string]interface{}{
					"tags": tags,
				}
				url := strings.Replace(ADDTAGE, ":serviceId", "XXX", 1)
				body, _ := json.Marshal(bodyParams)
				bodyBuf := bytes.NewReader(body)
				req, _ := http.NewRequest(POST, SCURL+url, bodyBuf)
				req.Header.Set("X-Domain-Name", "default")
				resp, err := scclient.Do(req)
				Expect(err).To(BeNil())
				defer resp.Body.Close()

				Expect(resp.StatusCode).To(Equal(http.StatusBadRequest))
			})
		})

		By("Get Micro-Service Tag API", func() {
			It("Get Tags for MicroService", func() {
				//Add Tag
				tags := map[string]interface{}{
					"testkey": "testValue",
				}

				bodyParams := map[string]interface{}{
					"tags": tags,
				}
				url := strings.Replace(ADDTAGE, ":serviceId", serviceId, 1)
				body, _ := json.Marshal(bodyParams)
				bodyBuf := bytes.NewReader(body)
				req, _ := http.NewRequest(POST, SCURL+url, bodyBuf)
				req.Header.Set("X-Domain-Name", "default")
				resp, err := scclient.Do(req)
				Expect(err).To(BeNil())
				defer resp.Body.Close()

				Expect(resp.StatusCode).To(Equal(http.StatusOK))

				//Get Tags
				<-time.After(time.Second)
				url = strings.Replace(GETTAGS, ":serviceId", serviceId, 1)
				req, _ = http.NewRequest(GET, SCURL+url, nil)
				req.Header.Set("X-Domain-Name", "default")
				req.Header.Set("X-ConsumerId", serviceId)
				resp, _ = scclient.Do(req)
				respbody, _ := ioutil.ReadAll(resp.Body)
				Expect(resp.StatusCode).To(Equal(http.StatusOK))
				tagsStruct := map[string]interface{}{}
				json.Unmarshal(respbody, &tagsStruct)
				Expect(tagsStruct).To(Equal(bodyParams))
			})

			It("Get Empty Tags for MicroService", func() {
				//Get Tags
				url := strings.Replace(GETTAGS, ":serviceId", serviceId, 1)
				req, _ := http.NewRequest(GET, SCURL+url, nil)
				req.Header.Set("X-Domain-Name", "default")
				req.Header.Set("X-ConsumerId", serviceId)
				resp, _ := scclient.Do(req)
				respbody, _ := ioutil.ReadAll(resp.Body)
				Expect(resp.StatusCode).To(Equal(http.StatusOK))
				Expect(string(bytes.TrimSpace(respbody))).To(Equal("{}"))
			})

			It("Get Tags for Invalid MicroService", func() {
				//Get Tags
				url := strings.Replace(GETTAGS, ":serviceId", "XXXX", 1)
				req, _ := http.NewRequest(GET, SCURL+url, nil)
				req.Header.Set("X-Domain-Name", "default")
				resp, _ := scclient.Do(req)
				Expect(resp.StatusCode).To(Equal(http.StatusBadRequest))
			})

		})
		By("Update Micro-Service Tag API", func() {
			It("Update MicroService tag with proper value", func() {
				//Add Tag
				tags := map[string]interface{}{
					"testkey": "testValue",
				}

				bodyParams := map[string]interface{}{
					"tags": tags,
				}
				url := strings.Replace(ADDTAGE, ":serviceId", serviceId, 1)
				body, _ := json.Marshal(bodyParams)
				bodyBuf := bytes.NewReader(body)
				req, _ := http.NewRequest(POST, SCURL+url, bodyBuf)
				req.Header.Set("X-Domain-Name", "default")
				resp, err := scclient.Do(req)
				Expect(err).To(BeNil())
				defer resp.Body.Close()

				Expect(resp.StatusCode).To(Equal(http.StatusOK))

				//Update Tags
				<-time.After(time.Second)
				url = strings.Replace(UPDATETAG, ":serviceId", serviceId, 1)
				url = strings.Replace(url, ":key", "testkey", 1)
				req, _ = http.NewRequest(UPDATE, SCURL+url+"?value=newValue", nil)
				req.Header.Set("X-Domain-Name", "default")
				resp, err = scclient.Do(req)
				Expect(err).To(BeNil())
				defer resp.Body.Close()
				Expect(resp.StatusCode).To(Equal(http.StatusOK))

				//Verify the Tags
				<-time.After(time.Second)
				url = strings.Replace(GETTAGS, ":serviceId", serviceId, 1)
				req, _ = http.NewRequest(GET, SCURL+url, nil)
				req.Header.Set("X-Domain-Name", "default")
				req.Header.Set("X-ConsumerId", serviceId)
				resp, _ = scclient.Do(req)
				respbody, _ := ioutil.ReadAll(resp.Body)
				Expect(resp.StatusCode).To(Equal(http.StatusOK))
				tagsStruct := map[string]interface{}{}
				json.Unmarshal(respbody, &tagsStruct)
				tags = map[string]interface{}{
					"testkey": "newValue",
				}

				newTags := map[string]interface{}{
					"tags": tags,
				}
				Expect(tagsStruct).To(Equal(newTags))
			})

			It("Update MicroService tag with non-exsisting tags", func() {
				//Add Tag
				tags := map[string]interface{}{
					"testkey": "testValue",
				}

				bodyParams := map[string]interface{}{
					"tags": tags,
				}
				url := strings.Replace(ADDTAGE, ":serviceId", serviceId, 1)
				body, _ := json.Marshal(bodyParams)
				bodyBuf := bytes.NewReader(body)
				req, _ := http.NewRequest(POST, SCURL+url, bodyBuf)
				req.Header.Set("X-Domain-Name", "default")
				resp, err := scclient.Do(req)
				Expect(err).To(BeNil())
				defer resp.Body.Close()

				Expect(resp.StatusCode).To(Equal(http.StatusOK))

				//Update Tags
				<-time.After(time.Second)
				url = strings.Replace(UPDATETAG, ":serviceId", serviceId, 1)
				url = strings.Replace(url, ":key", "unknownkey", 1)
				req, _ = http.NewRequest(UPDATE, SCURL+url+"?value=newValue", nil)
				req.Header.Set("X-Domain-Name", "default")
				resp, err = scclient.Do(req)
				Expect(err).To(BeNil())
				defer resp.Body.Close()
				Expect(resp.StatusCode).To(Equal(http.StatusBadRequest))

			})

			It("Update MicroService tag with non-exsisting serviceID", func() {
				url := strings.Replace(UPDATETAG, ":serviceId", "XXXXX", 1)
				url = strings.Replace(url, ":key", "unknownkey", 1)
				req, _ := http.NewRequest(UPDATE, SCURL+url+"?value=newValue", nil)
				req.Header.Set("X-Domain-Name", "default")
				resp, err := scclient.Do(req)
				Expect(err).To(BeNil())
				defer resp.Body.Close()
				Expect(resp.StatusCode).To(Equal(http.StatusBadRequest))
			})

		})
		By("Delete Micro-Service Tag API", func() {
			It("Delete MicroService tag with proper value", func() {
				//Add Tag
				tags := map[string]interface{}{
					"testkey": "testValue",
				}

				bodyParams := map[string]interface{}{
					"tags": tags,
				}
				url := strings.Replace(ADDTAGE, ":serviceId", serviceId, 1)
				body, _ := json.Marshal(bodyParams)
				bodyBuf := bytes.NewReader(body)
				req, _ := http.NewRequest(POST, SCURL+url, bodyBuf)
				req.Header.Set("X-Domain-Name", "default")
				resp, err := scclient.Do(req)
				Expect(err).To(BeNil())
				defer resp.Body.Close()

				Expect(resp.StatusCode).To(Equal(http.StatusOK))

				//Delete the tag
				<-time.After(time.Second)
				url = strings.Replace(DELETETAG, ":serviceId", serviceId, 1)
				url = strings.Replace(url, ":key", "testkey", 1)
				req, _ = http.NewRequest(DELETE, SCURL+url, nil)
				req.Header.Set("X-Domain-Name", "default")
				resp, err = scclient.Do(req)
				Expect(err).To(BeNil())
				defer resp.Body.Close()
				Expect(resp.StatusCode).To(Equal(http.StatusOK))

				//verify Delete
				<-time.After(time.Second)
				url = strings.Replace(GETTAGS, ":serviceId", serviceId, 1)
				req, _ = http.NewRequest(GET, SCURL+url, nil)
				req.Header.Set("X-Domain-Name", "default")
				req.Header.Set("X-ConsumerId", serviceId)
				resp, _ = scclient.Do(req)
				respbody, _ := ioutil.ReadAll(resp.Body)
				Expect(resp.StatusCode).To(Equal(http.StatusOK))
				Expect(string(bytes.TrimSpace(respbody))).To(Equal("{}"))
			})

			It("Delete MicroService tag with non-exsisting tags", func() {
				//Add Tag
				tags := map[string]interface{}{
					"testkey": "testValue",
				}

				bodyParams := map[string]interface{}{
					"tags": tags,
				}
				url := strings.Replace(ADDTAGE, ":serviceId", serviceId, 1)
				body, _ := json.Marshal(bodyParams)
				bodyBuf := bytes.NewReader(body)
				req, _ := http.NewRequest(POST, SCURL+url, bodyBuf)
				req.Header.Set("X-Domain-Name", "default")
				resp, err := scclient.Do(req)
				Expect(err).To(BeNil())
				defer resp.Body.Close()

				Expect(resp.StatusCode).To(Equal(http.StatusOK))

				//Delete the tag
				<-time.After(time.Second)
				url = strings.Replace(DELETETAG, ":serviceId", serviceId, 1)
				url = strings.Replace(url, ":key", "unknowTag", 1)
				req, _ = http.NewRequest(DELETE, SCURL+url, nil)
				req.Header.Set("X-Domain-Name", "default")
				resp, err = scclient.Do(req)
				Expect(err).To(BeNil())
				defer resp.Body.Close()
				Expect(resp.StatusCode).To(Equal(http.StatusBadRequest))

				//verify Non-deleted of exsiting tag
				<-time.After(time.Second)
				url = strings.Replace(GETTAGS, ":serviceId", serviceId, 1)
				req, _ = http.NewRequest(GET, SCURL+url, nil)
				req.Header.Set("X-Domain-Name", "default")
				req.Header.Set("X-ConsumerId", serviceId)
				resp, _ = scclient.Do(req)
				respbody, _ := ioutil.ReadAll(resp.Body)
				Expect(resp.StatusCode).To(Equal(http.StatusOK))
				tagsStruct := map[string]interface{}{}
				json.Unmarshal(respbody, &tagsStruct)
				Expect(tagsStruct).To(Equal(bodyParams))
			})

			It("Delete MicroService tag with non-exsiting service id", func() {
				//Delete the tag
				url := strings.Replace(DELETETAG, ":serviceId", "XXX", 1)
				url = strings.Replace(url, ":key", "testkey", 1)
				req, _ := http.NewRequest(DELETE, SCURL+url, nil)
				req.Header.Set("X-Domain-Name", "default")
				resp, err := scclient.Do(req)
				Expect(err).To(BeNil())
				defer resp.Body.Close()
				Expect(resp.StatusCode).To(Equal(http.StatusBadRequest))
			})
		})
	})
})
