package dkms

import (
	"context"
	"fmt"
	"os"
	"os/exec"

	"cos.googlesource.com/cos/tools.git/src/pkg/gcs"
	"github.com/golang/glog"
)

// Unbuild removes a module from the DKMS build tree and uninstalls it.
//
// This removes the compiled modules from the build directory, then calls
// the MAKE clean command for the package from the package's build directory.
func Unbuild(pkg *Package) error {
	if !IsBuilt(pkg) {
		glog.Info("module is not built; skipping removal from build tree")
		return nil
	}

	if err := Uninstall(pkg); err != nil {
		return err
	}

	for _, module := range pkg.Config.Modules {
		builtModulePath := module.BuiltPath()
		glog.Info("removing built module", builtModulePath)
		if err := os.Remove(builtModulePath); err != nil {
			return err
		}
	}

	if err := clean(pkg.BuildDir(), pkg.Config.Clean); err != nil {
		return fmt.Errorf("failed to clean modules: %v", err)
	}

	return nil
}

func clean(dir string, command string) error {
	glog.Infof("cleaning with command: %s", command)
	cmd := exec.Command("bash", "-c", command)
	cmd.Dir = dir
	out, err := cmd.CombinedOutput()
	if err == nil {
		glog.Info(string(out))
	} else {
		glog.Error(string(out))
		return err
	}

	return nil
}

// CachedUnbuild removes a package from the local DKMS build tree and from the
// cache build tree.
//
// If the package is installed, this will uninstall it.
func CachedUnbuild(ctx context.Context, pkg *Package, cache *gcs.GCSBucket) error {
	if err := Unbuild(pkg); err != nil {
		return err
	}

	if IsBuiltInCache(ctx, pkg, cache) {
		for _, module := range pkg.Config.Modules {
			builtModulePath := module.CacheBuiltPath()
			if err := cache.DeleteObject(ctx, builtModulePath); err != nil {
				return err
			}
		}
	}

	return nil
}
