// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package artifactory

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

	"go.fuchsia.dev/fuchsia/tools/build"
	"go.fuchsia.dev/fuchsia/tools/lib/logger"
	"go.fuchsia.dev/fuchsia/tools/lib/osmisc"
)

const (
	outputBreakpadSymsArg = "output_breakpad_syms"
	outputGSYMArg         = "output_gsym"
)

// DebugBinaryUploads parses the binary manifest associated to a build and
// returns a list of Uploads of debug binaries and a list of associated fuchsia
// build IDs.
func DebugBinaryUploads(ctx context.Context, mods *build.Modules, debugNamespace, buildidNamespace string) ([]Upload, []string, error) {
	return debugBinaryUploads(ctx, mods, debugNamespace, buildidNamespace)
}

func debugBinaryUploads(ctx context.Context, mods binModules, debugNamespace, buildidNamespace string) ([]Upload, []string, error) {
	bins := mods.Binaries()
	for _, pb := range mods.PrebuiltBinarySets() {
		if pb.Manifest == "" {
			continue
		}
		prebuiltBins, err := pb.Get(mods.BuildDir())
		// The manifest might not have been built, but that's okay.
		if os.IsNotExist(err) {
			continue
		} else if err != nil {
			return nil, nil, fmt.Errorf("failed to derive binaries from prebuilt binary set %q: %w", pb.Name, err)
		}
		bins = append(bins, prebuiltBins...)
	}

	var uploads []Upload
	var fuchsiaBuildIDs []string
	buildIDSet := make(map[string]struct{})

	breakpadEmitted, err := mods.Args().BoolValue(outputBreakpadSymsArg)
	if err != nil && err != build.ErrArgNotSet {
		return nil, nil, fmt.Errorf("failed to determine whether breakpad symbols were output in the build: %v", err)
	}
	gsymEmitted, err := mods.Args().BoolValue(outputGSYMArg)
	if err != nil && err != build.ErrArgNotSet {
		return nil, nil, fmt.Errorf("failed to determine whether GSYM was output in the build: %v", err)
	}

	for _, bin := range bins {
		id, err := bin.ELFBuildID(mods.BuildDir())
		// OK if there was no build ID found for an associated binary.
		if err == build.ErrBuildIDNotFound {
			continue
		} else if err != nil {
			return nil, nil, err
		}
		logger.Debugf(ctx, "%s -> %s, %s\n", id, bin.Debug, bin.Label)

		// Skip duplicate build IDs.
		if _, ok := buildIDSet[id]; ok {
			continue
		}
		buildIDSet[id] = struct{}{}

		// We upload all debug binaries to a flat namespace.
		debugSrc := filepath.Join(mods.BuildDir(), bin.Debug)
		debugBuilt, err := osmisc.FileExists(debugSrc)
		if err != nil {
			return nil, nil, fmt.Errorf("failed to determine if debug binary %q was built: %v", bin.Label, err)
		} else if !debugBuilt {
			return nil, nil, fmt.Errorf("something's wrong: we have a build ID for %q but no associated debug binary", bin.Label)
		}
		uploads = append(uploads, Upload{
			Source:      debugSrc,
			Destination: fmt.Sprintf("%s/%s.debug", debugNamespace, id),
			Deduplicate: true,
			Compress:    true,
		})

		// Upload in debuginfod API format.
		uploads = append(uploads, Upload{
			Source:      debugSrc,
			Destination: fmt.Sprintf("%s/%s/debuginfo", buildidNamespace, id),
			Deduplicate: true,
			Compress:    true,
		})
		if bin.Dist != "" {
			uploads = append(uploads, Upload{
				Source:      filepath.Join(mods.BuildDir(), bin.Dist),
				Destination: fmt.Sprintf("%s/%s/executable", buildidNamespace, id),
				Deduplicate: true,
				Compress:    true,
			})
		}

		// If we configured the build to output breakpad symbols, then
		// assert that the associated breakpad file here was present, as the
		// associated debug binary is.
		if breakpadEmitted {
			if bin.Breakpad == "" {
				if bin.OS == "fuchsia" {
					return nil, nil, fmt.Errorf("breakpad file for %q was not present in metadata", bin.Label)
				}
				// We're lenient on non-fuchsia binaries not having breakpad
				// files as we can't generate them for all hosts and languages.
				continue
			}
			breakpadSrc := filepath.Join(mods.BuildDir(), bin.Breakpad)
			breakpadBuilt, err := osmisc.FileExists(breakpadSrc)
			if err != nil {
				return nil, nil, fmt.Errorf("failed to determine if breakpad file for %q was built: %v", bin.Label, err)
			} else if !breakpadBuilt {
				return nil, nil, fmt.Errorf("breakpad file for %q was not built", bin.Label)
			}
			uploads = append(uploads, Upload{
				Source:      breakpadSrc,
				Destination: fmt.Sprintf("%s/%s.sym", debugNamespace, id),
				Deduplicate: true,
				Compress:    true,
			})
			uploads = append(uploads, Upload{
				Source:      breakpadSrc,
				Destination: fmt.Sprintf("%s/%s/breakpad", buildidNamespace, id),
				Deduplicate: true,
				Compress:    true,
			})
		}
		if gsymEmitted {
			if bin.GSYM == "" {
				if bin.OS == "fuchsia" {
					return nil, nil, fmt.Errorf("GSYM file for %q was not present in metadata", bin.Label)
				}
				continue
			}
			gsymSrc := filepath.Join(mods.BuildDir(), bin.GSYM)
			if gsymBuilt, err := osmisc.FileExists(gsymSrc); err != nil {
				return nil, nil, fmt.Errorf("failed to determine if GSYM file for %q was built: %v", bin.Label, err)
			} else if !gsymBuilt {
				return nil, nil, fmt.Errorf("gsym file for %q was not built", bin.Label)
			}
			uploads = append(uploads, Upload{
				Source:      gsymSrc,
				Destination: fmt.Sprintf("%s/%s.gsym", debugNamespace, id),
				Deduplicate: true,
				Compress:    true,
			})
			uploads = append(uploads, Upload{
				Source:      gsymSrc,
				Destination: fmt.Sprintf("%s/%s/gsym", buildidNamespace, id),
				Deduplicate: true,
				Compress:    true,
			})
		}

		// At this point, fuchsiaBuildIDs should reflect all binaries built
		// and *all* of their associated breakpad files if emitted in the build.
		if bin.OS == "fuchsia" {
			fuchsiaBuildIDs = append(fuchsiaBuildIDs, id)
		}
	}
	return uploads, fuchsiaBuildIDs, nil
}

type binModules interface {
	BuildDir() string
	Args() build.Args
	Binaries() []build.Binary
	PrebuiltBinarySets() []build.PrebuiltBinarySet
}
