package builder

import (
	"fmt"
	"strings"
)

// LanguageBuilder provides language-specific build configurations
type LanguageBuilder struct {
	builderImage string
	buildCmd     []string
	runCmd       []string
	ports        []int
}

func nodeJSBuilder(version string) (*LanguageBuilder, error) {
	if version == "" {
		version = "16"
	}

	return &LanguageBuilder{
		builderImage: fmt.Sprintf("node:%s-alpine", version),
		buildCmd: []string{
			"npm install",
			"npm run build",
		},
		runCmd: []string{"npm", "start"},
		ports:  []int{3000},
	}, nil
}

func pythonBuilder(version string) (*LanguageBuilder, error) {
	if version == "" {
		version = "3.9"
	}

	return &LanguageBuilder{
		builderImage: fmt.Sprintf("python:%s-slim", version),
		buildCmd: []string{
			"pip install -r requirements.txt",
		},
		runCmd: []string{"python", "app.py"},
		ports:  []int{8000},
	}, nil
}

func goBuilder(version string) (*LanguageBuilder, error) {
	if version == "" {
		version = "1.21"
	}

	return &LanguageBuilder{
		builderImage: fmt.Sprintf("golang:%s-alpine", version),
		buildCmd: []string{
			"go build -o app",
		},
		runCmd: []string{"./app"},
		ports:  []int{8080},
	}, nil
}

// Dockerfile returns the Dockerfile content for the language
func (b *LanguageBuilder) Dockerfile() string {
	var sb strings.Builder

	// Build stage
	sb.WriteString(fmt.Sprintf("FROM %s as builder\n", b.builderImage))
	sb.WriteString("WORKDIR /app\n")
	sb.WriteString("COPY . .\n")
	for _, cmd := range b.buildCmd {
		sb.WriteString(fmt.Sprintf("RUN %s\n", cmd))
	}

	// Runtime stage
	sb.WriteString(fmt.Sprintf("\nFROM %s\n", b.builderImage))
	sb.WriteString("WORKDIR /app\n")
	sb.WriteString("COPY --from=builder /app .\n")

	// Expose ports
	for _, port := range b.ports {
		sb.WriteString(fmt.Sprintf("EXPOSE %d\n", port))
	}

	// Set entrypoint
	sb.WriteString(fmt.Sprintf("CMD [\"%s\"", b.runCmd[0]))
	for _, arg := range b.runCmd[1:] {
		sb.WriteString(fmt.Sprintf(", \"%s\"", arg))
	}
	sb.WriteString("]\n")

	return sb.String()
}
