/*
 * 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"
	"net/http"
	"strings"

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

var _ = Describe("MicroService Api schema Test", func() {
	var serviceId string
	It("create microService", func() {
		schema := []string{"first_schemaId", "second_schemaId"}
		properties := map[string]string{"attr1": "aa"}
		servicemap := map[string]interface{}{
			"serviceName": "schema_test_serviceName",
			"appId":       "schema_test_appId",
			"version":     "1.0.0",
			"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)
		respbody, _ := ioutil.ReadAll(resp.Body)
		serviceId = gojson.Json(string(respbody)).Get("serviceId").Tostring()
		Expect(err).To(BeNil())
		defer resp.Body.Close()
	})
	It("create schema", func() {
		schema := map[string]string{"schema": "first_schema"}
		url := strings.Replace(UPDATESCHEMA, ":serviceId", serviceId, -1)
		url = strings.Replace(url, ":schemaId", "first_schemaId", 1)
		body, _ := json.Marshal(schema)
		bodyBuf := bytes.NewReader(body)
		req, _ := http.NewRequest(UPDATE, SCURL+url, bodyBuf)
		req.Header.Set("X-Domain-Name", "default")
		resp, err := scclient.Do(req)
		Expect(err).To(BeNil())
		Expect(resp.StatusCode).To(Equal(http.StatusOK))
		defer resp.Body.Close()
	})

	It("create schemas", func() {
		schema := map[string]string{
			"schema":   "second_schema",
			"summary":  "second0summary",
			"schemaId": "second_schemaId",
		}
		schemas := map[string][]map[string]string{
			"schemas": {
				schema,
			},
		}
		url := strings.Replace(UPDATESCHEMAS, ":serviceId", serviceId, 1)
		url = strings.Replace(url, ":schemaId", "second_schemaId", 1)
		body, _ := json.Marshal(schemas)
		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())
		Expect(resp.StatusCode).To(Equal(http.StatusOK))
		defer resp.Body.Close()
	})

	It("get schema", func() {
		url := strings.Replace(GETSCHEMABYID, ":serviceId", serviceId, 1)
		url = strings.Replace(url, ":schemaId", "second_schemaId", 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.StatusOK))
		defer resp.Body.Close()
	})

	It("get schemas", func() {
		url := strings.Replace(GETSCHEMAS, ":serviceId", serviceId, 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.StatusOK))
		defer resp.Body.Close()
	})

	It("delete schema", func() {
		url := strings.Replace(DELETESCHEMA, ":serviceId", serviceId, 1)
		url = strings.Replace(url, ":schemaId", "second_schemaId", 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))
		defer resp.Body.Close()
	})

	It("delete service", func() {

		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))
		defer resp.Body.Close()
	})
})
