/*
 *
 * Copyright 2019 gRPC authors.
 *
 * 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 bootstrap provides the functionality to initialize certain aspects
// of an xDS client by reading a bootstrap file.
package bootstrap

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"

	v2corepb "github.com/envoyproxy/go-control-plane/envoy/api/v2/core"
	v3corepb "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
	"github.com/golang/protobuf/jsonpb"
	"github.com/golang/protobuf/proto"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials/google"
	"google.golang.org/grpc/xds/internal/version"
)

const (
	// Environment variable which holds the name of the xDS bootstrap file.
	bootstrapFileEnv = "GRPC_XDS_BOOTSTRAP"
	// Environment variable which controls the use of xDS v3 API.
	v3SupportEnv = "GRPC_XDS_EXPERIMENTAL_V3_SUPPORT"
	// The "server_features" field in the bootstrap file contains a list of
	// features supported by the server. A value of "xds_v3" indicates that the
	// server supports the v3 version of the xDS transport protocol.
	serverFeaturesV3 = "xds_v3"

	// Type name for Google default credentials.
	credsGoogleDefault              = "google_default"
	credsInsecure                   = "insecure"
	gRPCUserAgentName               = "gRPC Go"
	clientFeatureNoOverprovisioning = "envoy.lb.does_not_support_overprovisioning"
)

var gRPCVersion = fmt.Sprintf("%s %s", gRPCUserAgentName, grpc.Version)

// For overriding in unit tests.
var bootstrapFileReadFunc = ioutil.ReadFile

// Config provides the xDS client with several key bits of information that it
// requires in its interaction with an xDS server. The Config is initialized
// from the bootstrap file.
type Config struct {
	// BalancerName is the name of the xDS server to connect to.
	//
	// The bootstrap file contains a list of servers (with name+creds), but we
	// pick the first one.
	BalancerName string
	// Creds contains the credentials to be used while talking to the xDS
	// server, as a grpc.DialOption.
	Creds grpc.DialOption
	// TransportAPI indicates the API version of xDS transport protocol to use.
	// This describes the xDS gRPC endpoint and version of
	// DiscoveryRequest/Response used on the wire.
	TransportAPI version.TransportAPI
	// NodeProto contains the Node proto to be used in xDS requests. The actual
	// type depends on the transport protocol version used.
	NodeProto proto.Message
}

type channelCreds struct {
	Type   string          `json:"type"`
	Config json.RawMessage `json:"config"`
}

type xdsServer struct {
	ServerURI    string         `json:"server_uri"`
	ChannelCreds []channelCreds `json:"channel_creds"`
}

// NewConfig returns a new instance of Config initialized by reading the
// bootstrap file found at ${GRPC_XDS_BOOTSTRAP}.
//
// The format of the bootstrap file will be as follows:
// {
//    "xds_server": {
//      "server_uri": <string containing URI of xds server>,
//      "channel_creds": [
//        {
//          "type": <string containing channel cred type>,
//          "config": <JSON object containing config for the type>
//        }
//      ],
//      "server_features": [ ... ]
//    },
//    "node": <JSON form of Node proto>
// }
//
// Currently, we support exactly one type of credential, which is
// "google_default", where we use the host's default certs for transport
// credentials and a Google oauth token for call credentials.
//
// This function tries to process as much of the bootstrap file as possible (in
// the presence of the errors) and may return a Config object with certain
// fields left unspecified, in which case the caller should use some sane
// defaults.
func NewConfig() (*Config, error) {
	config := &Config{}

	fName, ok := os.LookupEnv(bootstrapFileEnv)
	if !ok {
		return nil, fmt.Errorf("xds: Environment variable %v not defined", bootstrapFileEnv)
	}
	logger.Infof("Got bootstrap file location from %v environment variable: %v", bootstrapFileEnv, fName)

	data, err := bootstrapFileReadFunc(fName)
	if err != nil {
		return nil, fmt.Errorf("xds: Failed to read bootstrap file %s with error %v", fName, err)
	}
	logger.Debugf("Bootstrap content: %s", data)

	var jsonData map[string]json.RawMessage
	if err := json.Unmarshal(data, &jsonData); err != nil {
		return nil, fmt.Errorf("xds: Failed to parse file %s (content %v) with error: %v", fName, string(data), err)
	}

	serverSupportsV3 := false
	m := jsonpb.Unmarshaler{AllowUnknownFields: true}
	for k, v := range jsonData {
		switch k {
		case "node":
			// We unconditionally convert the JSON into a v3.Node proto. The v3
			// proto does not contain the deprecated field "build_version" from
			// the v2 proto. We do not expect the bootstrap file to contain the
			// "build_version" field. In any case, the unmarshal will succeed
			// because we have set the `AllowUnknownFields` option on the
			// unmarshaler.
			n := &v3corepb.Node{}
			if err := m.Unmarshal(bytes.NewReader(v), n); err != nil {
				return nil, fmt.Errorf("xds: jsonpb.Unmarshal(%v) for field %q failed during bootstrap: %v", string(v), k, err)
			}
			config.NodeProto = n
		case "xds_servers":
			var servers []*xdsServer
			if err := json.Unmarshal(v, &servers); err != nil {
				return nil, fmt.Errorf("xds: json.Unmarshal(%v) for field %q failed during bootstrap: %v", string(v), k, err)
			}
			if len(servers) < 1 {
				return nil, fmt.Errorf("xds: bootstrap file parsing failed during bootstrap: file doesn't contain any xds server to connect to")
			}
			xs := servers[0]
			config.BalancerName = xs.ServerURI
			for _, cc := range xs.ChannelCreds {
				// We stop at the first credential type that we support.
				if cc.Type == credsGoogleDefault {
					config.Creds = grpc.WithCredentialsBundle(google.NewDefaultCredentials())
					break
				} else if cc.Type == credsInsecure {
					config.Creds = grpc.WithInsecure()
					break
				}
			}
		case "server_features":
			var features []string
			if err := json.Unmarshal(v, &features); err != nil {
				return nil, fmt.Errorf("xds: json.Unmarshal(%v) for field %q failed during bootstrap: %v", string(v), k, err)
			}
			for _, f := range features {
				switch f {
				case serverFeaturesV3:
					serverSupportsV3 = true
				}
			}
		}
		// Do not fail the xDS bootstrap when an unknown field is seen. This can
		// happen when an older version client reads a newer version bootstrap
		// file with new fields.
	}

	if config.BalancerName == "" {
		return nil, fmt.Errorf("xds: Required field %q not found in bootstrap %s", "xds_servers.server_uri", jsonData["xds_servers"])
	}
	if config.Creds == nil {
		return nil, fmt.Errorf("xds: Required field %q doesn't contain valid value in bootstrap %s", "xds_servers.channel_creds", jsonData["xds_servers"])
	}

	// We end up using v3 transport protocol version only if the following
	// conditions are met:
	// 1. Server supports v3, indicated by the presence of "xds_v3" in
	//    server_features.
	// 2. Environment variable "GRPC_XDS_EXPERIMENTAL_V3_SUPPORT" is set to
	//    true.
	// The default value of the enum type "version.TransportAPI" is v2.
	//
	// TODO: there are multiple env variables, GRPC_XDS_BOOTSTRAP and
	// GRPC_XDS_EXPERIMENTAL_V3_SUPPORT. Move all env variables into a separate
	// package.
	if v3Env := os.Getenv(v3SupportEnv); v3Env == "true" {
		if serverSupportsV3 {
			config.TransportAPI = version.TransportV3
		}
	}

	if err := config.updateNodeProto(); err != nil {
		return nil, err
	}
	logger.Infof("Bootstrap config for creating xds-client: %+v", config)
	return config, nil
}

// updateNodeProto updates the node proto read from the bootstrap file.
//
// Node proto in Config contains a v3.Node protobuf message corresponding to the
// JSON contents found in the bootstrap file. This method performs some post
// processing on it:
// 1. If we don't find a nodeProto in the bootstrap file, we create an empty one
// here. That way, callers of this function can always expect that the NodeProto
// field is non-nil.
// 2. If the transport protocol version to be used is not v3, we convert the
// current v3.Node proto in a v2.Node proto.
// 3. Some additional fields which are not expected to be set in the bootstrap
// file are populated here.
func (c *Config) updateNodeProto() error {
	if c.TransportAPI == version.TransportV3 {
		v3, _ := c.NodeProto.(*v3corepb.Node)
		if v3 == nil {
			v3 = &v3corepb.Node{}
		}
		v3.UserAgentName = gRPCUserAgentName
		v3.UserAgentVersionType = &v3corepb.Node_UserAgentVersion{UserAgentVersion: grpc.Version}
		v3.ClientFeatures = append(v3.ClientFeatures, clientFeatureNoOverprovisioning)
		c.NodeProto = v3
		return nil
	}

	v2 := &v2corepb.Node{}
	if c.NodeProto != nil {
		v3, err := proto.Marshal(c.NodeProto)
		if err != nil {
			return fmt.Errorf("xds: proto.Marshal(%v): %v", c.NodeProto, err)
		}
		if err := proto.Unmarshal(v3, v2); err != nil {
			return fmt.Errorf("xds: proto.Unmarshal(%v): %v", v3, err)
		}
	}
	c.NodeProto = v2

	// BuildVersion is deprecated, and is replaced by user_agent_name and
	// user_agent_version. But the management servers are still using the old
	// field, so we will keep both set.
	v2.BuildVersion = gRPCVersion
	v2.UserAgentName = gRPCUserAgentName
	v2.UserAgentVersionType = &v2corepb.Node_UserAgentVersion{UserAgentVersion: grpc.Version}
	v2.ClientFeatures = append(v2.ClientFeatures, clientFeatureNoOverprovisioning)
	return nil
}
