// Copyright 2020 The LUCI 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 isolateimpl

import (
	"context"
	"io/ioutil"
	"os"
	"path/filepath"
	"testing"

	"github.com/bazelbuild/remote-apis-sdks/go/pkg/cas"
	"github.com/bazelbuild/remote-apis-sdks/go/pkg/digest"
	"github.com/bazelbuild/remote-apis-sdks/go/pkg/fakes"
	repb "github.com/bazelbuild/remote-apis/build/bazel/remote/execution/v2"
	"google.golang.org/protobuf/proto"

	"go.chromium.org/luci/auth"
	"go.chromium.org/luci/client/casclient"
	"go.chromium.org/luci/client/isolate"

	. "github.com/smartystreets/goconvey/convey"
	. "go.chromium.org/luci/common/testing/assertions"
)

func TestElideNestedPaths(t *testing.T) {
	t.Parallel()
	doElision := func(deps []string) []string {
		// Ignore OS-dependent path sep
		return elideNestedPaths(deps, "/")
	}

	Convey(`Mixed`, t, func() {
		deps := []string{
			"ab/foo",
			"ab/",
			"foo",
			"b/c/",
			"b/a",
			"b/c/a",
			"ab/cd/",
		}
		So(doElision(deps), ShouldResemble, []string{"ab/", "b/a", "b/c/", "foo"})
	})

	Convey(`All files`, t, func() {
		deps := []string{
			"ab/foo",
			"ab/cd/foo",
			"foo",
			"ab/bar",
		}
		So(doElision(deps), ShouldResemble, []string{"ab/bar", "ab/cd/foo", "ab/foo", "foo"})
	})

	Convey(`Cousin paths`, t, func() {
		deps := []string{
			"ab/foo", // This is a file
			"ab/cd/",
			"ab/ef/",
			"ab/bar",
		}
		So(doElision(deps), ShouldResemble, []string{"ab/bar", "ab/cd/", "ab/ef/", "ab/foo"})
	})

	Convey(`Interesting dirs`, t, func() {
		deps := []string{
			"a/b/",
			"a/b/c/",
			"a/bc/",
			"a/bc/d/",
			"a/bcd/",
			"a/c/",
		}
		// Make sure:
		// 1. "a/b/" elides "a/b/c/", but not "a/bc/"
		// 2. "a/bc/" elides "a/bc/d/", but not "a/bcd/"
		So(doElision(deps), ShouldResemble, []string{"a/b/", "a/bc/", "a/bcd/", "a/c/"})
	})

	Convey(`Interesting files`, t, func() {
		deps := []string{
			"a/b",
			"a/bc",
			"a/bcd",
			"a/c",
		}
		// Make sure "a/b" elides neither "a/bc" nor "a/bcd"
		So(doElision(deps), ShouldResemble, []string{"a/b", "a/bc", "a/bcd", "a/c"})
	})
}

func TestUploadToCAS(t *testing.T) {
	Convey(`Top-level Setup`, t, func() {
		// We need a top-level Convey so that the fake env is reset for each test cases.
		// See https://github.com/smartystreets/goconvey/wiki/Execution-order
		tmpDir := t.TempDir()
		fooContent := []byte("foo")
		barContent := []byte("bar")
		bazContent := []byte("baz")
		fooDg := digest.NewFromBlob(fooContent)
		barDg := digest.NewFromBlob(barContent)
		bazDg := digest.NewFromBlob(bazContent)
		fakeFlags := casclient.Flags{
			Instance: "foo",
		}
		var opts auth.Options

		e, cleanup := fakes.NewTestEnv(t)
		defer cleanup()
		run := baseCommandRun{
			clientFactory: func(ctx context.Context, addr string, instance string, opts auth.Options, readOnly bool) (*cas.Client, error) {
				conn, err := e.Server.NewClientConn(ctx)
				if err != nil {
					return nil, err
				}
				return cas.NewClientWithConfig(ctx, conn, "instance", casclient.DefaultConfig())
			},
		}
		cas := e.Server.CAS

		Convey(`Basic`, func() {
			isol1Content := `{
			  'variables': {
			    'files': [
			      'foo',
			      'bar',
			    ],
			  },
			}`
			isol2Content := `{
			  'variables': {
			    'files': [
			      'foo2',
			      'baz',
			    ],
			  },
			}`

			writeFile(tmpDir, "foo", fooContent)
			writeFile(tmpDir, "foo2", fooContent)
			writeFile(tmpDir, "bar", barContent)
			writeFile(tmpDir, "baz", bazContent)
			isol1Path := writeFile(tmpDir, "isol1.isolate", []byte(isol1Content))
			isol2Path := writeFile(tmpDir, "isol2.isolate", []byte(isol2Content))

			dgs, err := run.uploadToCAS(context.Background(), "", opts, &fakeFlags, nil, &isolate.ArchiveOptions{
				Isolate: isol1Path,
			}, &isolate.ArchiveOptions{
				Isolate: isol2Path,
			})
			So(err, ShouldBeNil)
			So(dgs, ShouldHaveLength, 2)

			isol1Dir := &repb.Directory{Files: []*repb.FileNode{
				{Name: "bar", Digest: barDg.ToProto()},
				{Name: "foo", Digest: fooDg.ToProto()},
			}}
			isol2Dir := &repb.Directory{Files: []*repb.FileNode{
				{Name: "baz", Digest: bazDg.ToProto()},
				{Name: "foo2", Digest: fooDg.ToProto()},
			}}
			blob, ok := cas.Get(dgs[0])
			So(ok, ShouldBeTrue)
			So(blob, ShouldResemble, mustMarshal(isol1Dir))
			blob, ok = cas.Get(dgs[1])
			So(ok, ShouldBeTrue)
			So(blob, ShouldResemble, mustMarshal(isol2Dir))

			So(cas.BlobWrites(fooDg), ShouldEqual, 1)
			So(cas.BlobWrites(barDg), ShouldEqual, 1)
			So(cas.BlobWrites(bazDg), ShouldEqual, 1)
		})

		Convey(`No upload if already on the server`, func() {
			isol1Content := `{
			  'variables': {
			    'files': [
			      'foo',
			      'bar',
			      'baz',
			    ],
			  },
			}`

			writeFile(tmpDir, "foo", fooContent)
			writeFile(tmpDir, "bar", barContent)
			writeFile(tmpDir, "baz", bazContent)
			isol1Path := writeFile(tmpDir, "isol1.isolate", []byte(isol1Content))

			// Upload `foo` and `bar` to the server
			cas.Put(fooContent)
			cas.Put(barContent)

			dgs, err := run.uploadToCAS(context.Background(), "", opts, &fakeFlags, nil, &isolate.ArchiveOptions{
				Isolate: isol1Path,
			})
			So(err, ShouldBeNil)
			So(dgs, ShouldHaveLength, 1)

			isol1Dir := &repb.Directory{Files: []*repb.FileNode{
				{Name: "bar", Digest: barDg.ToProto()},
				{Name: "baz", Digest: bazDg.ToProto()},
				{Name: "foo", Digest: fooDg.ToProto()},
			}}
			blob, ok := cas.Get(dgs[0])
			So(ok, ShouldBeTrue)
			So(blob, ShouldResemble, mustMarshal(isol1Dir))

			So(cas.BlobWrites(fooDg), ShouldEqual, 0)
			So(cas.BlobWrites(barDg), ShouldEqual, 0)
			So(cas.BlobWrites(bazDg), ShouldEqual, 1)
		})

		Convey(`Filter files`, func() {
			isol1Content := `{
			  'variables': {
			    'files': [
			      'filtered/foo',
			      'filtered/foo2',
			      'bar',
			    ],
			  },
			}`

			filteredDir := filepath.Join(tmpDir, "filtered")
			So(os.Mkdir(filteredDir, 0700), ShouldBeNil)
			writeFile(filteredDir, "foo", fooContent)
			writeFile(filteredDir, "foo2", fooContent)
			writeFile(tmpDir, "bar", barContent)
			isol1Path := writeFile(tmpDir, "isol1.isolate", []byte(isol1Content))

			dgs, err := run.uploadToCAS(context.Background(), "", opts, &fakeFlags, nil, &isolate.ArchiveOptions{
				Isolate:             isol1Path,
				IgnoredPathFilterRe: "filtered/foo",
			})
			So(err, ShouldBeNil)
			So(dgs, ShouldHaveLength, 1)

			// `foo*` files are filtered away
			isol1Dir := &repb.Directory{Files: []*repb.FileNode{
				{Name: "bar", Digest: barDg.ToProto()},
			}}
			blob, ok := cas.Get(dgs[0])
			So(ok, ShouldBeTrue)

			gotDir := &repb.Directory{}
			So(proto.Unmarshal(blob, gotDir), ShouldBeNil)
			So(gotDir, ShouldResembleProto, isol1Dir)

			So(cas.BlobWrites(fooDg), ShouldEqual, 0)
			So(cas.BlobWrites(barDg), ShouldEqual, 1)
		})
	})
}

func mustMarshal(p proto.Message) []byte {
	b, err := proto.Marshal(p)
	So(err, ShouldBeNil)
	return b
}

func writeFile(dir, name string, content []byte) string {
	p := filepath.Join(dir, name)
	So(ioutil.WriteFile(p, content, 0600), ShouldBeNil)
	return p
}
