// 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 lucicfg

import (
	"fmt"

	"go.starlark.net/starlark"
	"go.starlark.net/starlarkstruct"
)

// genCtx is a starlark struct that represents the state passed to generator
// callbacks (as first and only argument).
type genCtx struct {
	starlarkstruct.Struct

	output *outputBuilder
	roots  map[string]string // name of the set => its root directory
}

func newGenCtx() *genCtx {
	ctx := &genCtx{
		output: newOutputBuilder(),
		roots:  map[string]string{},
	}
	ctx.Struct = *starlarkstruct.FromStringDict(starlark.String("gen_ctx"), starlark.StringDict{
		"output":             ctx.output,
		"declare_config_set": starlark.NewBuiltin("declare_config_set", ctx.declareConfigSetImpl),
	})
	return ctx
}

func (c *genCtx) declareConfigSetImpl(_ *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
	var name starlark.String
	var root starlark.String
	err := starlark.UnpackArgs("declare_config_set", args, kwargs,
		"name", &name,
		"root", &root)
	if err != nil {
		return nil, err
	}
	nameS := name.GoString()

	// Paths must be within the config output directory, "../" is not allowed.
	rootS, err := cleanRelativePath("", root.GoString(), false)
	if err != nil {
		return nil, fmt.Errorf("declare_config_set: root - %s", err)
	}

	// It is OK to redeclare exact same root. It is not OK to change it.
	if existing, ok := c.roots[nameS]; ok && existing != rootS {
		return nil, fmt.Errorf("declare_config_set: set %q has already been declared", nameS)
	}
	c.roots[nameS] = rootS

	return starlark.None, nil
}

func (c *genCtx) assembleOutput(includePBHeader bool) (Output, error) {
	files, err := c.output.finalize(includePBHeader)
	return Output{
		Data:  files,
		Roots: c.roots,
	}, err
}

func init() {
	// new_gen_ctx() makes a new empty generator context object.
	declNative("new_gen_ctx", func(call nativeCall) (starlark.Value, error) {
		if err := call.unpack(0); err != nil {
			return nil, err
		}
		return newGenCtx(), nil
	})
}
