// Copyright 2018 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 main

import (
	"bytes"
	"context"
	"debug/elf"
	"encoding/hex"
	"encoding/json"
	"flag"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strconv"
	"strings"
	"sync"
	"time"

	"go.fuchsia.dev/fuchsia/tools/debug/covargs"
	"go.fuchsia.dev/fuchsia/tools/debug/covargs/api/llvm"
	"go.fuchsia.dev/fuchsia/tools/debug/symbolize"
	"go.fuchsia.dev/fuchsia/tools/lib/cache"
	"go.fuchsia.dev/fuchsia/tools/lib/color"
	"go.fuchsia.dev/fuchsia/tools/lib/flagmisc"
	"go.fuchsia.dev/fuchsia/tools/lib/logger"
	"go.fuchsia.dev/fuchsia/tools/lib/retry"
	"go.fuchsia.dev/fuchsia/tools/testing/runtests"
	"golang.org/x/sync/errgroup"
)

const (
	shardSize              = 1000
	symbolCacheSize        = 100
	cloudFetchMaxAttempts  = 2
	cloudFetchRetryBackoff = 500 * time.Millisecond
	cloudFetchTimeout      = 60 * time.Second
)

var (
	colors            color.EnableColor
	level             logger.LogLevel
	summaryFile       flagmisc.StringsValue
	buildIDDirPaths   flagmisc.StringsValue
	debuginfodServers flagmisc.StringsValue
	debuginfodCache   string
	symbolServers     flagmisc.StringsValue
	symbolCache       string
	coverageReport    bool
	dryRun            bool
	skipFunctions     bool
	outputDir         string
	llvmCov           string
	llvmProfdata      flagmisc.StringsValue
	outputFormat      string
	jsonOutput        string
	reportDir         string
	saveTemps         string
	basePath          string
	diffMappingFile   string
	compilationDir    string
	pathRemapping     flagmisc.StringsValue
	srcFiles          flagmisc.StringsValue
	numThreads        int
	jobs              int
)

func init() {
	colors = color.ColorAuto
	level = logger.InfoLevel

	flag.Var(&colors, "color", "can be never, auto, always")
	flag.Var(&level, "level", "can be fatal, error, warning, info, debug or trace")
	flag.Var(&summaryFile, "summary", "path to summary.json file. If given as `<path>=<version>`, the version should correspond "+
		"to the llvm-profdata required to run with the profiles from this summary.json")
	flag.Var(&buildIDDirPaths, "build-id-dir", "path to .build-id directory")
	flag.Var(&debuginfodServers, "debuginfod-server", "path to the debuginfod server")
	flag.StringVar(&debuginfodCache, "debuginfod-cache", "", "path to directory to store fetched debug binaries from debuginfodserver")
	flag.Var(&symbolServers, "symbol-server", "a GCS URL or bucket name that contains debug binaries indexed by build ID")
	flag.StringVar(&symbolCache, "symbol-cache", "", "path to directory to store cached debug binaries in")
	flag.BoolVar(&coverageReport, "coverage-report", true, "if set, generate a coverage report")
	flag.BoolVar(&dryRun, "dry-run", false, "if set the system prints out commands that would be run instead of running them")
	flag.BoolVar(&skipFunctions, "skip-functions", true, "if set, the coverage report enabled by the `report-dir` flag will not include function coverage")
	flag.StringVar(&outputDir, "output-dir", "", "the directory to output results to")
	flag.Var(&llvmProfdata, "llvm-profdata", "the location of llvm-profdata. If given as `<path>=<version>`, the version should correspond "+
		"to the summary containing profiles that this llvm-profdata tool should be used to run with")
	flag.StringVar(&llvmCov, "llvm-cov", "llvm-cov", "the location of llvm-cov")
	flag.StringVar(&outputFormat, "format", "html", "the output format used for llvm-cov")
	flag.StringVar(&jsonOutput, "json-output", "", "outputs profile information to the specified file")
	flag.StringVar(&saveTemps, "save-temps", "", "save temporary artifacts in a directory")
	flag.StringVar(&reportDir, "report-dir", "", "the directory to save the report to")
	flag.StringVar(&basePath, "base", "", "base path for source tree")
	flag.StringVar(&diffMappingFile, "diff-mapping", "", "path to diff mapping file")
	flag.StringVar(&compilationDir, "compilation-dir", "", "the directory used as a base for relative coverage mapping paths, passed through to llvm-cov")
	flag.Var(&pathRemapping, "path-equivalence", "<from>,<to> remapping of source file paths passed through to llvm-cov")
	flag.Var(&srcFiles, "src-file", "path to a source file to generate coverage for. If provided, only coverage for these files will be generated.\n"+
		"Multiple files can be specified with multiple instances of this flag.")
	flag.IntVar(&numThreads, "num-threads", 0, "number of processing threads")
	flag.IntVar(&jobs, "jobs", runtime.NumCPU(), "number of parallel jobs")
}

const llvmProfileSinkType = "llvm-profile"

func splitVersion(arg string) (version, value string) {
	version = ""
	s := strings.SplitN(arg, "=", 2)
	if len(s) > 1 {
		version = s[1]
	}
	return version, s[0]
}

// readSummary reads a summary file, and returns a mapping of unique profile to version.
func readSummary(summaryFiles []string) (map[string]string, error) {
	versionedSinks := make(map[string]runtests.DataSinkMap)

	for _, summaryFile := range summaryFiles {
		version, summaryFile := splitVersion(summaryFile)
		sinks, ok := versionedSinks[version]
		if !ok {
			sinks = make(runtests.DataSinkMap)
		}
		// TODO(phosek): process these in parallel using goroutines.
		file, err := os.Open(summaryFile)
		if err != nil {
			return nil, fmt.Errorf("cannot open %q: %w", summaryFile, err)
		}
		defer file.Close()

		var summary runtests.TestSummary
		if err := json.NewDecoder(file).Decode(&summary); err != nil {
			return nil, fmt.Errorf("cannot decode %q: %w", summaryFile, err)
		}

		dir := filepath.Dir(summaryFile)
		for _, detail := range summary.Tests {
			for name, data := range detail.DataSinks {
				for _, sink := range data {
					sinks[name] = append(sinks[name], runtests.DataSink{
						Name: sink.Name,
						File: filepath.Join(dir, sink.File),
					})
				}
			}
		}
		versionedSinks[version] = sinks
	}

	// Dedupe sinks.
	profiles := make(map[string]string)
	for version, summary := range versionedSinks {
		for _, sink := range summary[llvmProfileSinkType] {
			profiles[sink.File] = version
		}
	}

	return profiles, nil
}

type Action struct {
	Path string   `json:"cmd"`
	Args []string `json:"args"`
}

func (a Action) Run(ctx context.Context) ([]byte, error) {
	logger.Debugf(ctx, "%s\n", a.String())
	if !dryRun {
		return exec.Command(a.Path, a.Args...).CombinedOutput()
	}
	return nil, nil
}

func (a Action) String() string {
	var buf bytes.Buffer
	fmt.Fprint(&buf, a.Path)
	for _, arg := range a.Args {
		fmt.Fprintf(&buf, " %s", arg)
	}
	return buf.String()
}

// mergeProfiles merges raw profiles (.profraw) and returns a single indexed profile.
func mergeProfiles(ctx context.Context, tempDir string, profiles map[string]string, llvmProfDataVersions map[string]string) (string, error) {
	partitionedProfiles := make(map[string][]string)
	for profile, version := range profiles {
		partitionedProfiles[version] = append(partitionedProfiles[version], profile)
	}

	profdataFiles := []string{}
	for version, profileList := range partitionedProfiles {
		if len(profileList) == 0 {
			continue
		}

		// Make the llvm-profdata response file.
		profdataFile, err := os.Create(filepath.Join(tempDir, fmt.Sprintf("llvm-profdata%s.rsp", version)))
		if err != nil {
			return "", fmt.Errorf("creating llvm-profdata.rsp file: %w", err)
		}

		for _, profile := range profileList {
			fmt.Fprintf(profdataFile, "%s\n", profile)
		}
		profdataFile.Close()

		// Merge all raw profiles.
		mergedProfileFile := filepath.Join(tempDir, fmt.Sprintf("merged%s.profdata", version))
		args := []string{
			"merge",
			"--failure-mode=any",
			"--sparse",
			"--output", mergedProfileFile,
		}
		if numThreads != 0 {
			args = append(args, "--num-threads", strconv.Itoa(numThreads))
		}
		args = append(args, "@"+profdataFile.Name())

		// Find the associated llvm-profdata tool.
		llvmProfData, ok := llvmProfDataVersions[version]
		if !ok {
			return "", fmt.Errorf("no llvm-profdata has been specified for version %q", version)
		}
		mergeCmd := Action{Path: llvmProfData, Args: args}
		data, err := mergeCmd.Run(ctx)
		if err != nil {
			return "", fmt.Errorf("%s failed with %v:\n%s", mergeCmd.String(), err, string(data))
		}
		profdataFiles = append(profdataFiles, mergedProfileFile)
	}

	mergedProfileFile := filepath.Join(tempDir, "merged.profdata")
	args := []string{
		"merge",
		"--failure-mode=any",
		"--sparse",
		"--output", mergedProfileFile,
	}
	if numThreads != 0 {
		args = append(args, "--num-threads", strconv.Itoa(numThreads))
	}
	args = append(args, profdataFiles...)
	mergeCmd := Action{Path: llvmProfDataVersions[""], Args: args}
	data, err := mergeCmd.Run(ctx)
	if err != nil {
		return "", fmt.Errorf("%s failed with %v:\n%s", mergeCmd.String(), err, string(data))
	}

	return mergedProfileFile, nil
}

type profileReadingError struct {
	profile    string
	errMessage string
}

func (e *profileReadingError) Error() string {
	return fmt.Sprintf("cannot read profile %q: %q", e.profile, e.errMessage)
}

// readEmbeddedBuildId reads embedded build id from a profile by invoking llvm-profdata tool and returns it.
func readEmbeddedBuildId(ctx context.Context, tool string, profile string) (string, error) {
	args := []string{
		"show",
		"--binary-ids",
	}
	args = append(args, profile)
	readCmd := Action{Path: tool, Args: args}
	output, err := readCmd.Run(ctx)
	if err != nil {
		return "", &profileReadingError{profile, string(output)}
	}

	// Split the lines in llvm-profdata output, which should have the following lines for build ids.
	// Binary IDs:
	// 1696251c (This is an example for build id)
	splittedOutput := strings.Split((string(output)), "Binary IDs:")
	if len(splittedOutput) < 2 {
		return "", fmt.Errorf("invalid llvm-profdata output in profile %q: %w\n%s", profile, err, string(output))
	}

	embeddedBuildId := strings.TrimSpace(splittedOutput[len(splittedOutput)-1])
	if embeddedBuildId == "" {
		return "", fmt.Errorf("no build id found in profile %q:\n%s", profile, string(output))
	}
	// Check if embedded build id consists of hex characters.
	_, err = hex.DecodeString(embeddedBuildId)
	if err != nil {
		return "", fmt.Errorf("invalid build id in profile %q: %w", profile, err)
	}

	return embeddedBuildId, nil
}

type profileEntry struct {
	Profile string `json:"profile"`
	Module  string `json:"module"`
}

// createEntries creates a list of entries (profile and build id pairs) that is used to fetch binaries from symbol server.
func createEntries(ctx context.Context, profiles map[string]string, llvmProfDataVersions map[string]string) ([]profileEntry, error) {
	profileEntryChan := make(chan profileEntry, len(profiles))
	sems := make(chan struct{}, jobs)
	var eg errgroup.Group
	for profile, version := range profiles {
		profile := profile // capture range variable.
		version := version
		// Do not add the profiles that have debuginfod support because there is no need to fetch the associated binaries from symbol server for them.
		if len(debuginfodServers) > 0 {
			continue
		}
		sems <- struct{}{}
		eg.Go(func() error {
			defer func() { <-sems }()

			// Find the associated llvm-profdata tool.
			llvmProfData, ok := llvmProfDataVersions[version]
			if !ok {
				return fmt.Errorf("no llvm-profdata has been specified for version %q", version)
			}

			// Read embedded build ids.
			embeddedBuildId, err := readEmbeddedBuildId(ctx, llvmProfData, profile)
			if err != nil {
				return err
			}
			profileEntryChan <- profileEntry{
				Profile: profile,
				Module:  embeddedBuildId,
			}
			return nil
		})
	}

	if err := eg.Wait(); err != nil {
		return nil, err
	}

	close(profileEntryChan)

	var entries []profileEntry
	for pe := range profileEntryChan {
		entries = append(entries, pe)
	}

	return entries, nil
}

func isInstrumented(filepath string) bool {
	file, err := os.Open(filepath)
	if err != nil {
		return false
	}
	defer file.Close()
	if elfFile, err := elf.NewFile(file); err == nil {
		return elfFile.Section("__llvm_prf_cnts") != nil
	}
	return false
}

// fetchFromSymbolServer returns all the binaries that are fetched from the symbol server when symbol server option is provided.
func fetchFromSymbolServer(ctx context.Context, mergedProfileFile string, tempDir string, entries *[]profileEntry) ([]symbolize.FileCloser, error) {
	var fileCache *cache.FileCache
	if len(symbolServers) > 0 {
		if symbolCache == "" {
			return nil, fmt.Errorf("-symbol-cache must be set if a symbol server is used")
		}
		var err error
		if fileCache, err = cache.GetFileCache(symbolCache, symbolCacheSize); err != nil {
			return nil, err
		}
	}

	var repo symbolize.CompositeRepo
	for _, dir := range buildIDDirPaths {
		repo.AddRepo(symbolize.NewBuildIDRepo(dir))
	}

	for _, symbolServer := range symbolServers {
		cloudRepo, err := symbolize.NewCloudRepo(ctx, symbolServer, fileCache)
		if err != nil {
			return nil, err
		}
		cloudRepo.SetTimeout(cloudFetchTimeout)
		repo.AddRepo(cloudRepo)
	}

	// Gather the set of modules and coverage files.
	modules := []symbolize.FileCloser{}
	files := make(chan symbolize.FileCloser)
	malformedModules := make(chan string)
	s := make(chan struct{}, jobs)
	var wg sync.WaitGroup
	for _, entry := range *entries {
		wg.Add(1)
		go func(module string) {
			defer wg.Done()
			s <- struct{}{}
			defer func() { <-s }()
			var file symbolize.FileCloser
			if err := retry.Retry(ctx, retry.WithMaxAttempts(retry.NewConstantBackoff(cloudFetchRetryBackoff), cloudFetchMaxAttempts), func() error {
				var err error
				file, err = repo.GetBuildObject(module)
				return err
			}, nil); err != nil {
				logger.Warningf(ctx, "module with build id %s not found: %v\n", module, err)
				return
			}
			if isInstrumented(file.String()) {
				// Run llvm-cov with the individual module to make sure it's valid.
				args := []string{
					"show",
					"-instr-profile", mergedProfileFile,
					"-summary-only",
				}
				for _, remapping := range pathRemapping {
					args = append(args, "-path-equivalence", remapping)
				}
				args = append(args, file.String())
				showCmd := Action{Path: llvmCov, Args: args}
				data, err := showCmd.Run(ctx)
				if err != nil {
					logger.Warningf(ctx, "module %s returned err %v:\n%s", module, err, string(data))
					file.Close()
					malformedModules <- module
				} else {
					files <- file
				}
			} else {
				file.Close()
			}
		}(entry.Module)
	}
	go func() {
		wg.Wait()
		close(malformedModules)
		close(files)
	}()
	var malformed []string
	go func() {
		for m := range malformedModules {
			malformed = append(malformed, m)
		}
	}()
	for f := range files {
		modules = append(modules, f)
	}

	// Write the malformed modules to a file in order to keep track of the tests affected by https://fxbug.dev/42153844.
	if err := os.WriteFile(filepath.Join(tempDir, "malformed_binaries.txt"), []byte(strings.Join(malformed, "\n")), os.ModePerm); err != nil {
		return modules, fmt.Errorf("failed to write malformed binaries to a file: %w", err)
	}

	return modules, nil
}

// createLLVMCovResponseFile adds fetched binaries to the llvm-cov response file.
func createLLVMCovResponseFile(tempDir string, modules *[]symbolize.FileCloser) (string, error) {
	// Make the llvm-cov response file.
	covFile, err := os.Create(filepath.Join(tempDir, "llvm-cov.rsp"))
	if err != nil {
		return "", fmt.Errorf("creating llvm-cov.rsp file: %w", err)
	}

	for i, module := range *modules {
		// llvm-cov expects a positional arg representing the first
		// object file before it processes the rest of the positional
		// args as source files, so we don't use an -object flag with
		// the first file.
		if i == 0 {
			fmt.Fprintf(covFile, "%s\n", module.String())
		} else {
			fmt.Fprintf(covFile, "-object %s\n", module.String())
		}
	}

	if len(srcFiles) > 0 {
		fmt.Fprintln(covFile, "-sources")
		for _, srcFile := range srcFiles {
			fmt.Fprintf(covFile, "%s\n", srcFile)
		}
	}

	covFile.Close()
	return covFile.Name(), nil
}

// setDebuginfodEnv sets the environment variables for debuginfod.
func setDebuginfodEnv(cmd *exec.Cmd) error {
	if len(debuginfodServers) > 0 {
		if debuginfodCache == "" {
			return fmt.Errorf("-debuginfod-cache must be set if debuginfod server is used")
		}

		debuginfodUrls := strings.Join(debuginfodServers, " ")
		cmd.Env = os.Environ()
		// Set DEBUGINFOD_URLS environment variable that is a string of a space-separated URLs.
		cmd.Env = append(cmd.Env, "DEBUGINFOD_URLS="+debuginfodUrls)
		cmd.Env = append(cmd.Env, "DEBUGINFOD_CACHE_PATH="+debuginfodCache)
	}

	return nil
}

// showCoverageData shows coverage data by invoking llvm-cov show command.
func showCoverageData(ctx context.Context, mergedProfileFile string, covFile string) error {
	// Make the output directory.
	err := os.MkdirAll(outputDir, os.ModePerm)
	if err != nil {
		return fmt.Errorf("creating output dir %s: %w", outputDir, err)
	}

	// Produce HTML report.
	args := []string{
		"show",
		"-format", outputFormat,
		"-instr-profile", mergedProfileFile,
		"-show-directory-coverage",
		"-output-dir", outputDir,
	}
	if compilationDir != "" {
		args = append(args, "-compilation-dir", compilationDir)
	}
	for _, remapping := range pathRemapping {
		args = append(args, "-path-equivalence", remapping)
	}

	args = append(args, "@"+covFile)
	showCmd := exec.Command(llvmCov, args...)
	logger.Debugf(ctx, "%s\n", showCmd)

	if err := setDebuginfodEnv(showCmd); err != nil {
		return fmt.Errorf("failed to set debuginfod environment: %w", err)
	}

	data, err := showCmd.CombinedOutput()
	if err != nil {
		return fmt.Errorf("%v:\n%s", err, string(data))
	}
	logger.Debugf(ctx, "%s\n", string(data))

	return nil
}

// exportCoverageData exports coverage data by invoking llvm-cov export command.
func exportCoverageData(ctx context.Context, mergedProfileFile string, covFile string, tempDir string) error {
	// Make the export directory.
	err := os.MkdirAll(reportDir, os.ModePerm)
	if err != nil {
		return fmt.Errorf("creating export dir %s: %w", reportDir, err)
	}

	stderrFilename := filepath.Join(tempDir, "llvm-cov.stderr.log")
	stderrFile, err := os.Create(stderrFilename)
	if err != nil {
		return fmt.Errorf("creating export %q: %w", stderrFilename, err)
	}
	defer stderrFile.Close()

	// Export data in machine readable format.
	var b bytes.Buffer
	args := []string{
		"export",
		"-instr-profile", mergedProfileFile,
		"-skip-expansions",
	}
	if skipFunctions {
		args = append(args, "-skip-functions")
	}
	for _, remapping := range pathRemapping {
		args = append(args, "-path-equivalence", remapping)
	}

	args = append(args, "@"+covFile)
	exportCmd := exec.Command(llvmCov, args...)
	logger.Debugf(ctx, "%s\n", exportCmd)
	exportCmd.Stdout = &b
	exportCmd.Stderr = stderrFile

	if err := setDebuginfodEnv(exportCmd); err != nil {
		return fmt.Errorf("failed to set debuginfod environment: %w", err)
	}

	if err := exportCmd.Run(); err != nil {
		return fmt.Errorf("failed to export: %w", err)
	}

	coverageFilename := filepath.Join(tempDir, "coverage.json")
	if err := os.WriteFile(coverageFilename, b.Bytes(), 0644); err != nil {
		return fmt.Errorf("writing coverage %q: %w", coverageFilename, err)
	}

	if coverageReport {
		var export llvm.Export
		if err := json.NewDecoder(&b).Decode(&export); err != nil {
			return fmt.Errorf("failed to load the exported file: %w", err)
		}

		var mapping *covargs.DiffMapping
		if diffMappingFile != "" {
			file, err := os.Open(diffMappingFile)
			if err != nil {
				return fmt.Errorf("cannot open %q: %w", diffMappingFile, err)
			}
			defer file.Close()

			if err := json.NewDecoder(file).Decode(mapping); err != nil {
				return fmt.Errorf("failed to load the diff mapping file: %w", err)
			}
		}

		files, err := covargs.ConvertFiles(&export, basePath, mapping)
		if err != nil {
			return fmt.Errorf("failed to convert files: %w", err)
		}

		if _, err := covargs.SaveReport(files, shardSize, reportDir); err != nil {
			return fmt.Errorf("failed to save report: %w", err)
		}
	}

	return nil
}

func process(ctx context.Context) error {
	llvmProfDataVersions := make(map[string]string)
	for _, profdata := range llvmProfdata {
		version, tool := splitVersion(profdata)
		llvmProfDataVersions[version] = tool
	}
	if _, ok := llvmProfDataVersions[""]; !ok {
		return fmt.Errorf("missing default llvm-profdata tool path")
	}

	versionedProfiles, err := readSummary(summaryFile)
	if err != nil {
		return fmt.Errorf("failed to read summary file: %w", err)
	}

	tempDir := saveTemps
	if saveTemps == "" {
		tempDir, err = os.MkdirTemp(saveTemps, "covargs")
		if err != nil {
			return fmt.Errorf("cannot create temporary dir: %w", err)
		}
		defer os.RemoveAll(tempDir)
	}

	start := time.Now()
	mergedProfileFile, err := mergeProfiles(ctx, tempDir, versionedProfiles, llvmProfDataVersions)
	logger.Debugf(ctx, "time to merge profiles: %.2f minutes\n", time.Since(start).Minutes())
	if err != nil {
		return fmt.Errorf("failed to merge profiles: %w", err)
	}

	entries, err := createEntries(ctx, versionedProfiles, llvmProfDataVersions)
	if jsonOutput != "" {
		file, err := os.Create(jsonOutput)
		if err != nil {
			return fmt.Errorf("creating profile output file: %w", err)
		}
		defer file.Close()
		if err := json.NewEncoder(file).Encode(entries); err != nil {
			return fmt.Errorf("writing profile information: %w", err)
		}
	}

	start = time.Now()
	modules, err := fetchFromSymbolServer(ctx, mergedProfileFile, tempDir, &entries)
	logger.Debugf(ctx, "time to fetch from symbol server: %.2f minutes\n", time.Since(start).Minutes())

	// Delete all the binary files that are fetched from symbol server.
	// Symbolize.FileCloser holds a reference to a file and deletes it after Close() is called.
	for _, f := range modules {
		defer f.Close()
	}
	if err != nil {
		return fmt.Errorf("failed to fetch from symbol server: %w", err)
	}

	covFile, err := createLLVMCovResponseFile(tempDir, &modules)
	if err != nil {
		return fmt.Errorf("failed to create llvm-cov response file: %w", err)
	}

	if outputDir != "" {
		start = time.Now()
		if err = showCoverageData(ctx, mergedProfileFile, covFile); err != nil {
			return fmt.Errorf("failed to show coverage data: %w", err)
		}
		logger.Debugf(ctx, "time to show coverage: %.2f minutes\n", time.Since(start).Minutes())
	}

	if reportDir != "" {
		start = time.Now()
		if err = exportCoverageData(ctx, mergedProfileFile, covFile, tempDir); err != nil {
			return fmt.Errorf("failed to export coverage data: %w", err)
		}
		logger.Debugf(ctx, "time to export coverage: %.2f minutes\n", time.Since(start).Minutes())
	}

	// Delete debuginfod cache, which includes all the binary files that are fetched from debuginfod server.
	if debuginfodCache != "" {
		if err := os.RemoveAll(debuginfodCache); err != nil {
			return fmt.Errorf("failed to remove debuginfod cache: %w", err)
		}
	}

	return nil
}

func main() {
	flag.Parse()
	log := logger.NewLogger(level, color.NewColor(colors), os.Stdout, os.Stderr, "")
	ctx := logger.WithLogger(context.Background(), log)

	if err := process(ctx); err != nil {
		log.Errorf("%v\n", err)
		os.Exit(1)
	}
}
