// Copyright 2019 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 base

import (
	"context"
	"fmt"
	"os"
	"path/filepath"

	"go.chromium.org/luci/common/logging"
	"go.chromium.org/luci/starlark/interpreter"

	"go.chromium.org/luci/lucicfg"
)

// GenerateConfigs executes the Starlark script and assembles final values for
// meta config.
//
// It is a common part of subcommands that generate configs.
//
// 'meta' is initial Meta config with default parameters, it will be mutated
// in-place to contain the final parameters (based on meta.config(...) calls in
// Starlark and the config populated via CLI flags, passed as 'flags'). 'flags'
// are also mutated in-place to rebase ConfigDir onto cwd.
func GenerateConfigs(ctx context.Context, inputFile string, meta, flags *lucicfg.Meta) (lucicfg.ConfigSet, error) {
	abs, err := filepath.Abs(inputFile)
	if err != nil {
		return nil, err
	}

	// Make sure the input file exists, to make the error message in this case be
	// more humane. lucicfg.Generate will formulate this error as "no such module"
	// which looks confusing.
	switch _, err := os.Stat(abs); {
	case os.IsNotExist(err):
		return nil, fmt.Errorf("no such file: %s", inputFile)
	case err != nil:
		return nil, err
	}

	// The directory with the input file becomes the root of the main package.
	root, main := filepath.Split(abs)

	// Generate everything, storing the result in memory.
	logging.Infof(ctx, "Generating configs...")
	state, err := lucicfg.Generate(ctx, lucicfg.Inputs{
		Code:         interpreter.FileSystemLoader(root),
		Entry:        main,
		TextPBHeader: "# Auto-generated by lucicfg.\n# Do not modify manually.\n\n",
	})
	if err != nil {
		return nil, err
	}

	// Config dir in the default meta, and if set from Starlark, is relative to
	// the main package root. It is relative to cwd ONLY when explicitly provided
	// via -config-dir CLI flag. Note that ".." is allowed.
	cwd, err := os.Getwd()
	if err != nil {
		return nil, err
	}
	meta.RebaseConfigDir(root)
	state.Meta.RebaseConfigDir(root)
	flags.RebaseConfigDir(cwd)

	// Figure out the final meta config: values set via starlark override
	// defaults, and values passed explicitly via CLI flags override what is
	// in starlark.
	meta.PopulateFromTouchedIn(&state.Meta)
	meta.PopulateFromTouchedIn(flags)
	meta.Log(ctx)

	return state.Configs, nil
}
