package main

import (
	"context"
	"fmt"
	"log"
	"os"

	"dagger.io/dagger"
)

const GOLINES_CONTAINER = "golang"
const GOLINES_VERSION = "github.com/segmentio/golines@v0.9.0"

type Opts struct {
	Path         string
	IgnoredFiles []string
}

type OptsFunc func(ctx context.Context, o *Opts) error

func withPath(path string) OptsFunc {
	return func(ctx context.Context, o *Opts) error {
		o.Path = path

		return nil
	}
}

func format(ctx context.Context, optsFuncs ...OptsFunc) error {
	opts := &Opts{
		Path: ".",
		IgnoredFiles: []string{
			".shuttle/",
		},
	}

	for _, f := range optsFuncs {
		err := f(ctx, opts)
		if err != nil {
			return fmt.Errorf("failed to apply options: %v", err)
		}
	}

	log.Println("dagger")
	log.Printf("%+v", os.Environ())

	client, err := dagger.Connect(ctx, dagger.WithLogOutput(os.Stderr))
	if err != nil {
		return fmt.Errorf("could not connect to dagger: %v", err)
	}

	hostDir := client.Host().
		Directory(opts.Path, dagger.HostDirectoryOpts{Exclude: opts.IgnoredFiles})

	golines := client.Container().
		From(GOLINES_CONTAINER).
		WithExec([]string{"go", "install", GOLINES_VERSION}).
		WithDirectory("/mnt/app", hostDir).
		WithExec([]string{"golines", "-w", "/mnt/app"})

	exitCode, err := golines.ExitCode(ctx)
	if err != nil {
		return fmt.Errorf("could not format code: %v", err)
	}
	if exitCode != 0 {
		return fmt.Errorf("formatting failed with exitcode: %d", exitCode)
	}

	exported, err := golines.Directory("/mnt/app").Export(ctx, opts.Path)
	if err != nil {
		return fmt.Errorf("failed to export to host: %v", err)
	}
	if !exported {
		return fmt.Errorf("failed to export, see stderr for reason")

	}

	return nil
}

func Format(ctx context.Context) error {
	return format(ctx)
}