// Copyright 2018 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 validation

import (
	"context"
	"fmt"
	"testing"

	"go.chromium.org/luci/common/errors"

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

func TestRuleSet(t *testing.T) {
	t.Parallel()

	Convey("With validator callback", t, func() {
		ctx := context.Background()

		type call struct {
			validatorID string
			configSet   string
			path        string
		}
		calls := []call{}

		validator := func(id string) Func {
			return func(ctx *Context, configSet, path string, content []byte) error {
				calls = append(calls, call{id, configSet, path})
				return nil
			}
		}

		Convey("Works", func() {
			r := NewRuleSet()

			r.Vars.Register("a", func(context.Context) (string, error) { return "a_val", nil })
			r.Vars.Register("b", func(context.Context) (string, error) { return "b_val", nil })

			r.Add("services/${a}", "paths/a", validator("rule_1"))
			r.Add("services/${a}", "paths/${b}", validator("rule_2"))
			r.Add("services/c", "paths/c", validator("rule_3"))
			r.Add("regex:services/.*", "paths/c", validator("rule_4"))

			patterns, err := r.ConfigPatterns(ctx)
			So(err, ShouldBeNil)

			type pair struct {
				configSet string
				path      string
			}
			asPairs := make([]pair, len(patterns))
			for i, p := range patterns {
				asPairs[i] = pair{p.ConfigSet.String(), p.Path.String()}
			}
			So(asPairs, ShouldResemble, []pair{
				{"exact:services/a_val", "exact:paths/a"},
				{"exact:services/a_val", "exact:paths/b_val"},
				{"exact:services/c", "exact:paths/c"},
				{"regex:^services/.*$", "exact:paths/c"},
			})

			callValidator := func(configSet, path string) {
				c := Context{Context: ctx}
				So(r.ValidateConfig(&c, configSet, path, []byte("body")), ShouldBeNil)
			}

			callValidator("services/unknown", "paths/a")
			callValidator("services/a_val", "paths/a")
			callValidator("services/a_val", "paths/b_val")
			callValidator("services/a_val", "paths/c")
			callValidator("services/c", "paths/c")

			So(calls, ShouldResemble, []call{
				{"rule_1", "services/a_val", "paths/a"},
				{"rule_2", "services/a_val", "paths/b_val"},
				{"rule_4", "services/a_val", "paths/c"},
				{"rule_3", "services/c", "paths/c"},
				{"rule_4", "services/c", "paths/c"},
			})
		})

		Convey("Error in the var callback", func() {
			r := NewRuleSet()
			r.Vars.Register("a", func(context.Context) (string, error) { return "", fmt.Errorf("boom") })
			r.Add("services/${a}", "paths/a", validator("rule_1"))
			err := r.ValidateConfig(&Context{Context: ctx}, "services/zzz", "some path", []byte("body"))
			So(err, ShouldErrLike, "boom")
		})

		Convey("Missing variables", func() {
			r := NewRuleSet()
			r.Vars.Register("a", func(context.Context) (string, error) { return "a_val", nil })
			r.Add("${zzz}", "a", validator("1"))
			r.Add("a", "${zzz}", validator("1"))

			_, err := r.ConfigPatterns(ctx)
			merr := err.(errors.MultiError)
			So(merr, ShouldHaveLength, 2)
			So(merr[0], ShouldErrLike,
				`config set pattern "exact:${zzz}": no placeholder named "zzz" is registered`)
			So(merr[1], ShouldErrLike,
				`path pattern "exact:${zzz}": no placeholder named "zzz" is registered`)

			err = r.ValidateConfig(&Context{Context: ctx}, "set", "path", nil)
			merr = err.(errors.MultiError)
			So(merr, ShouldHaveLength, 2)
			So(merr[0], ShouldErrLike,
				`config set pattern "exact:${zzz}": no placeholder named "zzz" is registered`)
			So(merr[1], ShouldErrLike,
				`path pattern "exact:${zzz}": no placeholder named "zzz" is registered`)
		})

		Convey("Pattern is validated", func() {
			r := NewRuleSet()
			r.Vars.Register("a", func(context.Context) (string, error) { return "a_val", nil })
			r.Add("unknown:${a}", "a", validator("1"))
			r.Add("a", "unknown:${a}", validator("1"))

			_, err := r.ConfigPatterns(ctx)
			merr := err.(errors.MultiError)
			So(merr, ShouldHaveLength, 2)
			So(merr[0], ShouldErrLike,
				`config set pattern "unknown:${a}": unknown pattern kind: "unknown"`)
			So(merr[1], ShouldErrLike,
				`path pattern "unknown:${a}": unknown pattern kind: "unknown"`)

			err = r.ValidateConfig(&Context{Context: ctx}, "set", "path", nil)
			merr = err.(errors.MultiError)
			So(merr, ShouldHaveLength, 2)
			So(merr[0], ShouldErrLike,
				`config set pattern "unknown:${a}": unknown pattern kind: "unknown"`)
			So(merr[1], ShouldErrLike,
				`path pattern "unknown:${a}": unknown pattern kind: "unknown"`)
		})
	})
}
