package dockerimg

import (
	"bytes"
	"context"
	"crypto/sha256"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"io/fs"
	"maps"
	"net/http"
	"slices"
	"strings"
	"text/template"

	"sketch.dev/ant"
)

func hashInitFiles(initFiles map[string]string) string {
	h := sha256.New()
	for _, path := range slices.Sorted(maps.Keys(initFiles)) {
		fmt.Fprintf(h, "%s\n%s\n\n", path, initFiles[path])
	}
	fmt.Fprintf(h, "docker template\n%s\n", dockerfileBase)
	return hex.EncodeToString(h.Sum(nil))
}

// TODO: add semgrep, prettier -- they require node/npm/etc which is more complicated than apk
// If/when we do this, add them into the list of available tools in bash.go.
const dockerfileBase = `FROM {{.From}}

RUN apk add bash git make jq sqlite gcc musl-dev linux-headers npm nodejs go github-cli ripgrep fzf python3 curl vim

ENV GOTOOLCHAIN=auto
ENV GOPATH=/go
ENV PATH="$GOPATH/bin:$PATH"

RUN go install golang.org/x/tools/cmd/goimports@latest
RUN go install golang.org/x/tools/gopls@latest
RUN go install mvdan.cc/gofumpt@latest

RUN mkdir -p /root/.cache/sketch/webui

{{.ExtraCmds}}

ARG GIT_USER_EMAIL
ARG GIT_USER_NAME

RUN git config --global user.email "$GIT_USER_EMAIL" && \
    git config --global user.name "$GIT_USER_NAME"

LABEL sketch_context="{{.InitFilesHash}}"
COPY . /app

WORKDIR /app{{.SubDir}}
RUN if [ -f go.mod ]; then go mod download; fi

CMD ["/bin/sketch"]`

// createDockerfile creates a Dockerfile for a git repo.
// It expects the relevant initFiles to have been provided.
// If the sketch binary is being executed in a sub-directory of the repository,
// the relative path is provided on subPathWorkingDir.
func createDockerfile(ctx context.Context, httpc *http.Client, antURL, antAPIKey string, initFiles map[string]string, subPathWorkingDir string) (string, error) {
	if subPathWorkingDir == "." {
		subPathWorkingDir = ""
	} else if subPathWorkingDir != "" && subPathWorkingDir[0] != '/' {
		subPathWorkingDir = "/" + subPathWorkingDir
	}
	toolCalled := false
	var dockerfileFROM, dockerfileExtraCmds string
	runDockerfile := func(ctx context.Context, input json.RawMessage) (string, error) {
		// TODO: unmarshal straight into a struct
		var m map[string]any
		if err := json.Unmarshal(input, &m); err != nil {
			return "", fmt.Errorf(`input=%[1]v (%[1]T), wanted a map[string]any, got: %w`, input, err)
		}
		var ok bool
		dockerfileFROM, ok = m["from"].(string)
		if !ok {
			return "", fmt.Errorf(`input["from"]=%[1]v (%[1]T), wanted a string`, m["path"])
		}
		dockerfileExtraCmds, ok = m["extra_cmds"].(string)
		if !ok {
			return "", fmt.Errorf(`input["extra_cmds"]=%[1]v (%[1]T), wanted a string`, m["path"])
		}
		toolCalled = true
		return "OK", nil
	}
	convo := ant.NewConvo(ctx, antAPIKey)
	if httpc != nil {
		convo.HTTPC = httpc
	}
	if antURL != "" {
		convo.URL = antURL
	}
	convo.Tools = []*ant.Tool{{
		Name:        "dockerfile",
		Description: "Helps define a Dockerfile that sets up a dev environment for this project.",
		Run:         runDockerfile,
		InputSchema: ant.MustSchema(`{
  "type": "object",
  "required": ["from", "extra_cmds"],
  "properties": {
    "from": {
	  "type": "string",
	  "description": "The alpine base image provided to the dockerfile FROM command"
	},
    "extra_cmds": {
      "type": "string",
      "description": "Extra commands to add to the dockerfile."
    }
  }
}`),
	}}

	// TODO: it's basically impossible to one-shot a python env. We need an agent loop for that.
	// Right now the prompt contains a set of half-baked workarounds.

	// If you want to edit the model prompt, run:
	//
	//	go test ./dockerimg -httprecord ".*" -rewritewant
	//
	// Then look at the changes with:
	//
	//	git diff dockerimg/testdata/*.dockerfile
	//
	// If the dockerfile changes are a strict improvement, commit all the changes.
	msg := ant.Message{
		Role: ant.MessageRoleUser,
		Content: []ant.Content{{
			Type: ant.ContentTypeText,
			Text: `
Call the dockerfile tool to create a Dockerfile.
The parameters to dockerfile fill out the From and ExtraCmds
template variables in the following Go template:

` + "```\n" + dockerfileBase + "\n```" + `

In particular:
- Assume it is primarily a Go project. For a minimal env, prefer 1.24.2-alpine3.21 as a base image.
- If any python is needed at all, switch to using a python alpine image as a the base and apk add go.
  Favor using uv, and use one of these base images, depending on the preferred python version:
    ghcr.io/astral-sh/uv:python3.13-alpine
    ghcr.io/astral-sh/uv:python3.12-alpine
    ghcr.io/astral-sh/uv:python3.11-alpine
- When using pip to install packages, use: uv pip install --system.
- Python env setup is challenging and often no required, so any RUN commands involving python tooling should be written to let docker build continue if there is a failure.
- Include any tools particular to this repository that can be inferred from the given context.
- Append || true to any apk add commands in case the package does not exist.
- Do not expose any ports.
`,
		}},
	}
	if len(initFiles) > 0 {
		msg.Content[0].Text += "Here is the content of several files from the repository that may be relevant:\n\n"
	}

	for _, name := range slices.Sorted(maps.Keys(initFiles)) {
		msg.Content = append(msg.Content, ant.Content{
			Type: ant.ContentTypeText,
			Text: fmt.Sprintf("Here is the contents %s:\n<file>\n%s\n</file>\n\n", name, initFiles[name]),
		})
	}
	msg.Content = append(msg.Content, ant.Content{
		Type: ant.ContentTypeText,
		Text: "Now call the dockerfile tool.",
	})
	res, err := convo.SendMessage(msg)
	if err != nil {
		return "", err
	}
	if res.StopReason != ant.StopReasonToolUse {
		return "", fmt.Errorf("expected stop reason %q, got %q", ant.StopReasonToolUse, res.StopReason)
	}
	if _, err := convo.ToolResultContents(context.TODO(), res); err != nil {
		return "", err
	}
	if !toolCalled {
		return "", fmt.Errorf("no dockerfile returned")
	}

	buf := new(bytes.Buffer)
	err = template.Must(template.New("dockerfile").Parse(dockerfileBase)).Execute(buf, map[string]string{
		"From":          dockerfileFROM,
		"ExtraCmds":     dockerfileExtraCmds,
		"InitFilesHash": hashInitFiles(initFiles),
		"SubDir":        subPathWorkingDir,
	})
	if err != nil {
		return "", fmt.Errorf("dockerfile template failed: %w", err)
	}

	return buf.String(), nil
}

// For future reference: we can find the current git branch/checkout with: git symbolic-ref -q --short HEAD || git describe --tags --exact-match 2>/dev/null || git rev-parse HEAD

func readInitFiles(fsys fs.FS) (map[string]string, error) {
	result := make(map[string]string)

	err := fs.WalkDir(fsys, ".", func(path string, d fs.DirEntry, err error) error {
		if err != nil {
			return err
		}
		if d.IsDir() && (d.Name() == ".git" || d.Name() == "node_modules") {
			return fs.SkipDir
		}
		if !d.Type().IsRegular() {
			return nil
		}

		// Case 1: Check for README files
		// TODO: find README files between the .git root (where we start)
		// and the dir that sketch was initialized. This needs more info
		// plumbed to this function.
		if strings.HasPrefix(strings.ToLower(path), "readme") {
			content, err := fs.ReadFile(fsys, path)
			if err != nil {
				return err
			}
			result[path] = string(content)
			return nil
		}

		// Case 2: Check for GitHub workflow files
		if strings.HasPrefix(path, ".github/workflows/") {
			content, err := fs.ReadFile(fsys, path)
			if err != nil {
				return err
			}
			result[path] = string(content)
			return nil
		}

		return nil
	})
	if err != nil {
		return nil, err
	}
	return result, nil
}
