// Copyright 2020 The Monogon Project Authors.
//
// SPDX-License-Identifier: Apache-2.0
//
// 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 main

import (
	"encoding/json"
	"fmt"
	"log"
	"os"
	"os/exec"
	"path/filepath"

	"github.com/bazelbuild/bazel-gazelle/label"
)

// dependency is an external Go package/module, requested by the user of Fietsje directly or indirectly.
type dependency struct {
	// importpath is the Go import path that was used to import this dependency.
	importpath string
	// version at which this dependency has been requested. This can be in any form that `go get` or the go module
	// system understands.
	version string

	// locked is the 'resolved' version of a dependency, containing information about the dependency's hash, etc.
	locked *locked

	// parent is the dependency that pulled in this one, or nil if pulled in by the user.
	parent *dependency

	shelf *shelf

	// Build specific settings passed to gazelle.
	disableProtoBuild    bool
	forceBazelGeneration bool
	buildTags            []string
	patches              []string
	prePatches           []string
	buildExtraArgs       []string
	// replace is an importpath that this dependency will replace. If this is set, this dependency will be visible
	// in the build as 'importpath', but downloaded at 'replace'/'version'. This might be slighly confusing, but
	// follows the semantics of what Gazelle exposes via 'replace' in 'go_repository'.
	replace string
}

func (d *dependency) remoteImportpath() string {
	if d.replace != "" {
		return d.replace
	}
	return d.importpath
}

// locked is information about a dependency resolved from the go module system. It is expensive to get, and as such
// it is cached both in memory (as .locked in a dependency) and in the shelf.
type locked struct {
	// bazelName is the external workspace name that Bazel should use for this dependency, eg. com_github_google_glog.
	bazelName string
	// sum is the gomod compatible checksum of the depdendency, egh1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=.
	sum string
	// semver is the gomod-compatible version of this dependency. If the dependency was requested by git hash that does
	// not resolve to a particular release, this will be in the form of v0.0.0-20200520133742-deadbeefcafe.
	semver string
}

// child creates a new child dependence for this dependency, ie. one where the 'parent' pointer points to the dependency
// on which this method is called.
func (d *dependency) child(importpath, version string) *dependency {
	return &dependency{
		importpath: importpath,
		version:    version,
		shelf:      d.shelf,
		parent:     d,
	}
}

func (d *dependency) String() string {
	if d.replace != "" {
		return fmt.Sprintf("%s@%s (replacing %s)", d.replace, d.version, d.importpath)
	}
	return fmt.Sprintf("%s@%s", d.importpath, d.version)
}

// lock ensures that this dependency is locked, which means that it has been resolved to a particular, stable version
// and VCS details. We lock a dependency by either asking the go module subsystem (via a go module proxy or a download),
// or by consulting the shelf as a cache.
func (d *dependency) lock() error {
	// If already locked in-memory, use that.
	if d.locked != nil {
		return nil
	}

	// If already locked in the shelf, use that.
	if shelved := d.shelf.get(d.remoteImportpath(), d.version); shelved != nil {
		d.locked = shelved
		return nil
	}

	// Otherwise, download module.
	semver, _, sum, err := d.download()
	if err != nil {
		return fmt.Errorf("could not download: %v", err)
	}

	// And resolve its bazelName.
	name := label.ImportPathToBazelRepoName(d.importpath)

	// Hack for github.com/google/gvisor: it requests @com_github_opencontainers_runtime-spec.
	// We fix the generated name for this repo so it conforms to what gvisor expects.
	// TODO(q3k): instead of this, patch gvisor?
	if name == "com_github_opencontainers_runtime_spec" {
		name = "com_github_opencontainers_runtime-spec"
	}

	d.locked = &locked{
		bazelName: name,
		sum:       sum,
		semver:    semver,
	}
	log.Printf("%s: locked to %s", d, d.locked)

	// Save locked version to shelf.
	d.shelf.put(d.remoteImportpath(), d.version, d.locked)
	return d.shelf.save()
}

func (l *locked) String() string {
	return fmt.Sprintf("%s@%s", l.bazelName, l.sum)
}

// download ensures that this dependency is download locally, and returns the download location and the dependency's
// gomod-compatible sum.
func (d *dependency) download() (version, dir, sum string, err error) {
	goroot := os.Getenv("GOROOT")
	if goroot == "" {
		err = fmt.Errorf("GOROOT must be set")
		return
	}
	goTool := filepath.Join(goroot, "bin", "go")

	query := fmt.Sprintf("%s@%s", d.remoteImportpath(), d.version)
	cmd := exec.Command(goTool, "mod", "download", "-json", "--", query)
	out, err := cmd.Output()
	if err != nil {
		log.Printf("go mod returned: %q", out)
		err = fmt.Errorf("go mod failed: %v", err)
		return
	}

	var res struct{ Version, Sum, Dir string }
	err = json.Unmarshal(out, &res)
	if err != nil {
		return
	}

	version = res.Version
	dir = res.Dir
	sum = res.Sum
	return
}
