//Copyright 2017 Huawei Technologies Co., Ltd
//
//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 rest

import (
	"crypto/tls"
	"crypto/x509"
	"encoding/pem"
	"github.com/ServiceComb/service-center/pkg/common"
	"github.com/ServiceComb/service-center/pkg/security"
	"github.com/ServiceComb/service-center/util"
	"github.com/astaxie/beego"
	"io/ioutil"
	"time"
)

const (
	DEFAULT_TLS_HANDSHAKE_TIMEOUT = 30 * time.Second
	DEFAULT_HTTP_RESPONSE_TIMEOUT = 60 * time.Second
)

const HTTP_ERROR_STATUS_CODE = 600

const (
	HTTP_METHOD_GET    = "GET"
	HTTP_METHOD_PUT    = "PUT"
	HTTP_METHOD_POST   = "POST"
	HTTP_METHOD_DELETE = "DELETE"
)

func isValidMethod(method string) bool {
	switch method {
	case HTTP_METHOD_GET, HTTP_METHOD_PUT, HTTP_METHOD_POST, HTTP_METHOD_DELETE:
		return true
	default:
		return false
	}
}

func getX509CACertPool() (caCertPool *x509.CertPool, err error) {
	pool := x509.NewCertPool()
	caCertFile := common.GetServerSSLConfig().CACertFile
	caCert, err := ioutil.ReadFile(caCertFile)
	if err != nil {
		util.LOGGER.Errorf(err, "read ca cert file %s failed.", caCertFile)
		return nil, err
	}

	pool.AppendCertsFromPEM(caCert)
	return pool, nil
}

func loadTLSCertificate() (tlsCert []tls.Certificate, err error) {
	certFile, keyFile := common.GetServerSSLConfig().CertFile, common.GetServerSSLConfig().KeyFile
	passphase := common.GetServerSSLConfig().KeyPassphase
	plainPassphase, err := security.CipherPlugins[beego.AppConfig.DefaultString("cipher_plugin", "default")]().Decrypt(passphase)
	if err != nil {
		util.LOGGER.Errorf(err, "decrypt ssl passphase(%d) failed.", len(passphase))
		plainPassphase = ""
	}

	certContent, err := ioutil.ReadFile(certFile)
	if err != nil {
		util.LOGGER.Errorf(err, "read cert file %s failed.", certFile)
		return nil, err
	}

	keyContent, err := ioutil.ReadFile(keyFile)
	if err != nil {
		util.LOGGER.Errorf(err, "read key file %s failed.", keyFile)
		return nil, err
	}

	keyBlock, _ := pem.Decode(keyContent)
	if keyBlock == nil {
		util.LOGGER.Errorf(err, "decode key file %s failed.", keyFile)
		return nil, err
	}

	if x509.IsEncryptedPEMBlock(keyBlock) {
		plainPassphaseBytes := []byte(plainPassphase)
		keyData, err := x509.DecryptPEMBlock(keyBlock, plainPassphaseBytes)
		util.ClearStringMemory(&plainPassphase)
		util.ClearByteMemory(plainPassphaseBytes)
		if err != nil {
			util.LOGGER.Errorf(err, "decrypt key file %s failed.", keyFile)
			return nil, err
		}

		// 解密成功，重新编码为PEM格式的文件
		plainKeyBlock := &pem.Block{
			Type:  "RSA PRIVATE KEY",
			Bytes: keyData,
		}

		keyContent = pem.EncodeToMemory(plainKeyBlock)
	}

	cert, err := tls.X509KeyPair(certContent, keyContent)
	if err != nil {
		util.LOGGER.Errorf(err, "load X509 key pair from cert file %s with key file %s failed.", certFile, keyFile)
		return nil, err
	}

	var certs []tls.Certificate
	certs = append(certs, cert)

	return certs, nil
}

/**
  verifyPeer    Whether verify client
  supplyCert    Whether send certificate
  verifyCN      Whether verify CommonName
*/
func GetClientTLSConfig(verifyPeer bool, supplyCert bool, verifyCN bool) (tlsConfig *tls.Config, err error) {
	var pool *x509.CertPool = nil
	var certs []tls.Certificate
	if verifyPeer {
		pool, err = getX509CACertPool()
		if err != nil {
			return nil, err
		}
	}

	if supplyCert {
		certs, err = loadTLSCertificate()
		if err != nil {
			return nil, err
		}
	}

	tlsConfig = &tls.Config{
		RootCAs:            pool,
		Certificates:       certs,
		CipherSuites:       common.GetClientSSLConfig().CipherSuites,
		InsecureSkipVerify: !verifyCN,
		MinVersion:         common.GetClientSSLConfig().MinVersion,
		MaxVersion:         common.GetClientSSLConfig().MaxVersion,
	}

	return tlsConfig, nil
}

func GetServerTLSConfig(verifyPeer bool) (tlsConfig *tls.Config, err error) {
	clientAuthMode := tls.NoClientCert
	var pool *x509.CertPool = nil
	if verifyPeer {
		pool, err = getX509CACertPool()
		if err != nil {
			return nil, err
		}

		clientAuthMode = tls.RequireAndVerifyClientCert
	}

	var certs []tls.Certificate
	certs, err = loadTLSCertificate()
	if err != nil {
		return nil, err
	}

	tlsConfig = &tls.Config{
		ClientCAs:                pool,
		Certificates:             certs,
		CipherSuites:             common.GetServerSSLConfig().CipherSuites,
		PreferServerCipherSuites: true,
		ClientAuth:               clientAuthMode,
		MinVersion:               common.GetServerSSLConfig().MinVersion,
		MaxVersion:               common.GetServerSSLConfig().MaxVersion,
	}

	return tlsConfig, nil
}

func GetClient(communiType string) (*HttpClient, error) {
	verifyClient := false
	var err error
	var client *HttpClient
	//client, err = rest.GetHttpsClient(verifyClient)
	if communiType == "https" {
		client, err = GetAnnoHttpsClient(verifyClient)
		if err != nil {
			util.LOGGER.Error("Create https rest.client failed.", err)
			return nil, err
		}
		return client, nil
	}
	client, err = GetHttpClient(true)
	if err != nil {
		util.LOGGER.Error("Create http rest.client failed.", err)
		return nil, err
	}
	return client, nil
}
