/*
 *
 * Copyright 2018 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 alts

import (
	"context"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"regexp"
	"runtime"
	"strings"

	"google.golang.org/grpc/peer"
)

const (
	linuxProductNameFile     = "/sys/class/dmi/id/product_name"
	windowsCheckCommand      = "powershell.exe"
	windowsCheckCommandArgs  = "Get-WmiObject -Class Win32_BIOS"
	powershellOutputFilter   = "Manufacturer"
	windowsManufacturerRegex = ":(.*)"
)

type platformError string

func (k platformError) Error() string {
	return fmt.Sprintf("%s is not supported", string(k))
}

var (
	// The following two variables will be reassigned in tests.
	runningOS          = runtime.GOOS
	manufacturerReader = func() (io.Reader, error) {
		switch runningOS {
		case "linux":
			return os.Open(linuxProductNameFile)
		case "windows":
			cmd := exec.Command(windowsCheckCommand, windowsCheckCommandArgs)
			out, err := cmd.Output()
			if err != nil {
				return nil, err
			}

			for _, line := range strings.Split(strings.TrimSuffix(string(out), "\n"), "\n") {
				if strings.HasPrefix(line, powershellOutputFilter) {
					re := regexp.MustCompile(windowsManufacturerRegex)
					name := re.FindString(line)
					name = strings.TrimLeft(name, ":")
					return strings.NewReader(name), nil
				}
			}

			return nil, errors.New("cannot determine the machine's manufacturer")
		default:
			return nil, platformError(runningOS)
		}
	}
	vmOnGCP bool
)

// isRunningOnGCP checks whether the local system, without doing a network request is
// running on GCP.
func isRunningOnGCP() bool {
	manufacturer, err := readManufacturer()
	if err != nil {
		log.Fatalf("failure to read manufacturer information: %v", err)
	}
	name := string(manufacturer)
	switch runningOS {
	case "linux":
		name = strings.TrimSpace(name)
		return name == "Google" || name == "Google Compute Engine"
	case "windows":
		name = strings.Replace(name, " ", "", -1)
		name = strings.Replace(name, "\n", "", -1)
		name = strings.Replace(name, "\r", "", -1)
		return name == "Google"
	default:
		log.Fatal(platformError(runningOS))
	}
	return false
}

func readManufacturer() ([]byte, error) {
	reader, err := manufacturerReader()
	if err != nil {
		return nil, err
	}
	if reader == nil {
		return nil, errors.New("got nil reader")
	}
	manufacturer, err := ioutil.ReadAll(reader)
	if err != nil {
		return nil, fmt.Errorf("failed reading %v: %v", linuxProductNameFile, err)
	}
	return manufacturer, nil
}

// AuthInfoFromContext extracts the alts.AuthInfo object from the given context,
// if it exists. This API should be used by gRPC server RPC handlers to get
// information about the communicating peer. For client-side, use grpc.Peer()
// CallOption.
func AuthInfoFromContext(ctx context.Context) (AuthInfo, error) {
	p, ok := peer.FromContext(ctx)
	if !ok {
		return nil, errors.New("no Peer found in Context")
	}
	return AuthInfoFromPeer(p)
}

// AuthInfoFromPeer extracts the alts.AuthInfo object from the given peer, if it
// exists. This API should be used by gRPC clients after obtaining a peer object
// using the grpc.Peer() CallOption.
func AuthInfoFromPeer(p *peer.Peer) (AuthInfo, error) {
	altsAuthInfo, ok := p.AuthInfo.(AuthInfo)
	if !ok {
		return nil, errors.New("no alts.AuthInfo found in Peer")
	}
	return altsAuthInfo, nil
}
