package main

import "fmt"

// langkah merepresentasikan satu perintah pada stage build Dockerfile.
type langkah struct {
	nama  string // deskripsi perintah
	kunci string // input yang menentukan status cache layer
}

// langkahRilis adalah urutan perintah stage build pada Dockerfile multi-stage.
var langkahRilis = []langkah{
	{"FROM golang:1.27 AS build", "digest image dasar"},
	{"COPY go.mod go.sum", "isi go.mod + go.sum"},
	{"RUN go mod download", "daftar modul dari go.mod"},
	{"COPY . .", "seluruh isi direktori"},
	{"RUN go build", "source + flag build"},
}

// cacheMenentukan menghitung status cache tiap langkah dari layer yang berubah.
// Begitu satu layer MISS, seluruh layer setelahnya ikut dibangun ulang.
func cacheMenentukan(berubah map[string]bool) []string {
	var status []string
	missBerantai := false
	for _, l := range langkahRilis {
		if missBerantai || berubah[l.kunci] {
			missBerantai = true
			status = append(status, "MISS (build ulang)")
		} else {
			status = append(status, "HIT (dari cache)")
		}
	}
	return status
}

func main() {
	skenario := []struct {
		nama    string
		berubah map[string]bool
	}{
		{"tidak ada berkas berubah", nil},
		{"hanya main.go berubah", map[string]bool{"seluruh isi direktori": true}},
		{"go.mod berubah (dependensi baru)", map[string]bool{"isi go.mod + go.sum": true}},
	}
	for _, s := range skenario {
		fmt.Println("skenario:", s.nama)
		status := cacheMenentukan(s.berubah)
		for i, l := range langkahRilis {
			fmt.Printf("  %-28s %s\n", l.nama, status[i])
		}
		fmt.Println()
	}
}
