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

import (
	"fmt"
	"log"
	"os"
	"strings"

	"golang.org/x/mod/modfile"
)

// getTransitiveDeps is a hairy ball of heuristic used to find all recursively
// transitive dependencies of a given dependency. It downloads a given dependency
// using `go get`, and performs analysis of standard (go.mod/go.sum) and project-
// specific dependency management configuration/lock files in order to build a full
// view of all known, versioned transitive dependencies.
func (d *dependency) getTransitiveDeps() (map[string]*dependency, error) {
	// First, lock the dependency. Downloading it later will also return a sum, and we
	// want to ensure both are the same.
	err := d.lock()
	if err != nil {
		return nil, fmt.Errorf("could not lock: %v", err)
	}

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

	if sum != d.locked.sum {
		return nil, fmt.Errorf("inconsistent sum: %q downloaded, %q in shelf/lock", sum, d.locked.sum)
	}

	exists := func(p string) bool {
		full := fmt.Sprintf("%s/%s", path, p)
		if _, err := os.Stat(full); err == nil {
			return true
		}
		if err != nil && !os.IsExist(err) {
			panic(fmt.Sprintf("checking file %q: %v", full, err))
		}
		return false
	}

	read := func(p string) []byte {
		full := fmt.Sprintf("%s/%s", path, p)
		data, err := os.ReadFile(full)
		if err != nil {
			panic(fmt.Sprintf("reading file %q: %v", full, err))
		}
		return data
	}

	requirements := make(map[string]*dependency)

	// Read & parse go.mod if present.
	var mf *modfile.File
	if exists("go.mod") {
		log.Printf("%q: parsing go.mod\n", d.importpath)
		data := read("go.mod")
		mf, err = modfile.Parse("go.mod", data, nil)
		if err != nil {
			return nil, fmt.Errorf("parsing go.mod in %s: %v", d.importpath, err)
		}
	}

	// If a go.mod file was present, interpret it to populate dependencies.
	if mf != nil {
		for _, req := range mf.Require {
			requirements[req.Mod.Path] = d.child(req.Mod.Path, req.Mod.Version)
		}
		for _, rep := range mf.Replace {
			// skip filesystem rewrites
			if rep.New.Version == "" {
				continue
			}

			requirements[rep.New.Path] = d.child(rep.New.Path, rep.New.Version)
		}
	}

	// Read parse, and interpret. go.sum if present.
	// This should bring into view all recursively transitive dependencies.
	if exists("go.sum") {
		log.Printf("%q: parsing go.sum", d.importpath)
		data := read("go.sum")
		for _, line := range strings.Split(string(data), "\n") {
			line = strings.TrimSpace(line)
			if line == "" {
				continue
			}

			parts := strings.Fields(line)
			if len(parts) != 3 {
				return nil, fmt.Errorf("parsing go.sum: unparseable line %q", line)
			}

			importpath, version := parts[0], parts[1]

			// Skip if already created from go.mod.
			// TODO(q3k): error if go.sum and go.mod disagree?
			if _, ok := requirements[importpath]; ok {
				continue
			}

			if strings.HasSuffix(version, "/go.mod") {
				version = strings.TrimSuffix(version, "/go.mod")
			}
			requirements[importpath] = d.child(importpath, version)
		}
	}

	// Special case: root Kubernetes repo - rewrite staging/ deps to k8s.io/ at correct
	// versions, quit early. Kubernetes vendors all dependencies into vendor/, and also
	// contains sub-projects (components) in staging/. This converts all staging
	// dependencies into appropriately versioned k8s.io/<dep> paths.
	if d.importpath == "k8s.io/kubernetes" {
		log.Printf("%q: special case for Kubernetes main repository", d.importpath)
		if mf == nil {
			return nil, fmt.Errorf("k8s.io/kubernetes needs a go.mod")
		}
		// extract the version, turn into component version
		version := d.version
		if !strings.HasPrefix(version, "v") {
			return nil, fmt.Errorf("invalid version format for k8s: %q", version)
		}
		version = version[1:]
		componentVersion := fmt.Sprintf("kubernetes-%s", version)

		// find all k8s.io 'components'
		components := make(map[string]bool)
		for _, rep := range mf.Replace {
			if !strings.HasPrefix(rep.Old.Path, "k8s.io/") || !strings.HasPrefix(rep.New.Path, "./staging/src/") {
				continue
			}
			components[rep.Old.Path] = true
		}

		// add them to planner at the 'kubernetes-$ver' tag
		for component, _ := range components {
			requirements[component] = d.child(component, componentVersion)
		}
		return requirements, nil
	}

	// Special case: github.com/containerd/containerd: read vendor.conf.
	if d.importpath == "github.com/containerd/containerd" {
		log.Printf("%q: special case for containerd", d.importpath)
		if !exists("vendor.conf") {
			panic("containerd needs vendor.conf")
		}
		data := read("vendor.conf")
		for _, line := range strings.Split(string(data), "\n") {
			// strip comments
			parts := strings.SplitN(line, "#", 2)
			line = parts[0]

			// skip empty contents
			line = strings.TrimSpace(line)
			if line == "" {
				continue
			}

			// read dep/version pairs
			parts = strings.Fields(line)
			if len(parts) < 2 {
				return nil, fmt.Errorf("unparseable line in containerd vendor.conf: %q", line)
			}
			importpath, version := parts[0], parts[1]
			requirements[importpath] = d.child(importpath, version)
		}
		return requirements, nil
	}

	return requirements, nil
}
