// +build linux windows

/*
 *
 * 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"
	"io"
	"os"
	"strings"
	"testing"
	"time"

	"google.golang.org/grpc/codes"
	altspb "google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp"
	"google.golang.org/grpc/peer"
	"google.golang.org/grpc/status"
)

const (
	testServiceAccount1 = "service_account1"
	testServiceAccount2 = "service_account2"
	testServiceAccount3 = "service_account3"

	defaultTestTimeout = 10 * time.Second
)

func setupManufacturerReader(testOS string, reader func() (io.Reader, error)) func() {
	tmpOS := runningOS
	tmpReader := manufacturerReader

	// Set test OS and reader function.
	runningOS = testOS
	manufacturerReader = reader
	return func() {
		runningOS = tmpOS
		manufacturerReader = tmpReader
	}

}

func setup(testOS string, testReader io.Reader) func() {
	reader := func() (io.Reader, error) {
		return testReader, nil
	}
	return setupManufacturerReader(testOS, reader)
}

func setupError(testOS string, err error) func() {
	reader := func() (io.Reader, error) {
		return nil, err
	}
	return setupManufacturerReader(testOS, reader)
}

func (s) TestIsRunningOnGCP(t *testing.T) {
	for _, tc := range []struct {
		description string
		testOS      string
		testReader  io.Reader
		out         bool
	}{
		// Linux tests.
		{"linux: not a GCP platform", "linux", strings.NewReader("not GCP"), false},
		{"Linux: GCP platform (Google)", "linux", strings.NewReader("Google"), true},
		{"Linux: GCP platform (Google Compute Engine)", "linux", strings.NewReader("Google Compute Engine"), true},
		{"Linux: GCP platform (Google Compute Engine) with extra spaces", "linux", strings.NewReader("  Google Compute Engine        "), true},
		// Windows tests.
		{"windows: not a GCP platform", "windows", strings.NewReader("not GCP"), false},
		{"windows: GCP platform (Google)", "windows", strings.NewReader("Google"), true},
		{"windows: GCP platform (Google) with extra spaces", "windows", strings.NewReader("  Google     "), true},
	} {
		reverseFunc := setup(tc.testOS, tc.testReader)
		if got, want := isRunningOnGCP(), tc.out; got != want {
			t.Errorf("%v: isRunningOnGCP()=%v, want %v", tc.description, got, want)
		}
		reverseFunc()
	}
}

func (s) TestIsRunningOnGCPNoProductNameFile(t *testing.T) {
	reverseFunc := setupError("linux", os.ErrNotExist)
	if isRunningOnGCP() {
		t.Errorf("ErrNotExist: isRunningOnGCP()=true, want false")
	}
	reverseFunc()
}

func (s) TestAuthInfoFromContext(t *testing.T) {
	ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
	defer cancel()
	altsAuthInfo := &fakeALTSAuthInfo{}
	p := &peer.Peer{
		AuthInfo: altsAuthInfo,
	}
	for _, tc := range []struct {
		desc    string
		ctx     context.Context
		success bool
		out     AuthInfo
	}{
		{
			"working case",
			peer.NewContext(ctx, p),
			true,
			altsAuthInfo,
		},
	} {
		authInfo, err := AuthInfoFromContext(tc.ctx)
		if got, want := (err == nil), tc.success; got != want {
			t.Errorf("%v: AuthInfoFromContext(_)=(err=nil)=%v, want %v", tc.desc, got, want)
		}
		if got, want := authInfo, tc.out; got != want {
			t.Errorf("%v:, AuthInfoFromContext(_)=(%v, _), want (%v, _)", tc.desc, got, want)
		}
	}
}

func (s) TestAuthInfoFromPeer(t *testing.T) {
	altsAuthInfo := &fakeALTSAuthInfo{}
	p := &peer.Peer{
		AuthInfo: altsAuthInfo,
	}
	for _, tc := range []struct {
		desc    string
		p       *peer.Peer
		success bool
		out     AuthInfo
	}{
		{
			"working case",
			p,
			true,
			altsAuthInfo,
		},
	} {
		authInfo, err := AuthInfoFromPeer(tc.p)
		if got, want := (err == nil), tc.success; got != want {
			t.Errorf("%v: AuthInfoFromPeer(_)=(err=nil)=%v, want %v", tc.desc, got, want)
		}
		if got, want := authInfo, tc.out; got != want {
			t.Errorf("%v:, AuthInfoFromPeer(_)=(%v, _), want (%v, _)", tc.desc, got, want)
		}
	}
}

func (s) TestClientAuthorizationCheck(t *testing.T) {
	ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
	defer cancel()
	altsAuthInfo := &fakeALTSAuthInfo{testServiceAccount1}
	p := &peer.Peer{
		AuthInfo: altsAuthInfo,
	}
	for _, tc := range []struct {
		desc                    string
		ctx                     context.Context
		expectedServiceAccounts []string
		success                 bool
		code                    codes.Code
	}{
		{
			"working case",
			peer.NewContext(ctx, p),
			[]string{testServiceAccount1, testServiceAccount2},
			true,
			codes.OK, // err is nil, code is OK.
		},
		{
			"working case (case ignored)",
			peer.NewContext(ctx, p),
			[]string{strings.ToUpper(testServiceAccount1), testServiceAccount2},
			true,
			codes.OK, // err is nil, code is OK.
		},
		{
			"context does not have AuthInfo",
			ctx,
			[]string{testServiceAccount1, testServiceAccount2},
			false,
			codes.PermissionDenied,
		},
		{
			"unauthorized client",
			peer.NewContext(ctx, p),
			[]string{testServiceAccount2, testServiceAccount3},
			false,
			codes.PermissionDenied,
		},
	} {
		err := ClientAuthorizationCheck(tc.ctx, tc.expectedServiceAccounts)
		if got, want := (err == nil), tc.success; got != want {
			t.Errorf("%v: ClientAuthorizationCheck(_, %v)=(err=nil)=%v, want %v", tc.desc, tc.expectedServiceAccounts, got, want)
		}
		if got, want := status.Code(err), tc.code; got != want {
			t.Errorf("%v: ClientAuthorizationCheck(_, %v).Code=%v, want %v", tc.desc, tc.expectedServiceAccounts, got, want)
		}
	}
}

type fakeALTSAuthInfo struct {
	peerServiceAccount string
}

func (*fakeALTSAuthInfo) AuthType() string            { return "" }
func (*fakeALTSAuthInfo) ApplicationProtocol() string { return "" }
func (*fakeALTSAuthInfo) RecordProtocol() string      { return "" }
func (*fakeALTSAuthInfo) SecurityLevel() altspb.SecurityLevel {
	return altspb.SecurityLevel_SECURITY_NONE
}
func (f *fakeALTSAuthInfo) PeerServiceAccount() string                 { return f.peerServiceAccount }
func (*fakeALTSAuthInfo) LocalServiceAccount() string                  { return "" }
func (*fakeALTSAuthInfo) PeerRPCVersions() *altspb.RpcProtocolVersions { return nil }
