package main

import (
	"io/fs"
	"os"
	"path"
	"testing"

	"gotest.tools/v3/assert"
)

const expectedScript string = `#!/usr/bin/env bash

# AUTOGENERATED FILE - edit versions in ./component-versions.json.
# If you are adding components, modify this scripts' template in
# ./cmd/update-knative-components/main.go.
# You can regenerate locally with "make generate-kn-components-local".

set_versions() {
	# Note: Kubernetes Version node image per Kind releases (full hash is suggested):
	# https://github.com/kubernetes-sigs/kind/releases
	kind_node_version=v1.30

	# gets updated programatically via workflow -> PR creation
	knative_serving_version="v1.2.3"
	knative_eventing_version="v1.4.5"
	contour_version="v1.4.6"
}
`

const expectedJson string = `{
	"KindNode": "v1.30",
	"Serving": "v1.2.3",
	"Eventing": "v1.4.5",
	"Contour": "v1.4.6"
}
`

// TestRead should just successfully unmarshal ('v' struct & json compatibility)
func TestRead(t *testing.T) {
	dir := t.TempDir()

	const jsonContent string = `{
	"Serving": "v1.14",
	"Eventing": "v1.15",
	"Contour": "v1.61",
	"KindNode": "1.3456"
}
`
	tmpJson := path.Join(dir, "json.json")
	err := os.WriteFile(tmpJson, []byte(jsonContent), fs.ModePerm)
	if err != nil {
		t.Fatal(err)
	}

	_, err = readVersions(tmpJson)
	if err != nil {
		t.Fatalf("failed to read json: %v", err)
	}
}

// TestWrite ensures that writing both files succeeds with the correct file
// contents
func TestWrite(t *testing.T) {
	dir := t.TempDir()

	tmpJson := path.Join(dir, "f.json")
	tmpSh := path.Join(dir, "f.sh")

	v := Versions{
		Serving:  "v1.2.3",
		Eventing: "v1.4.5",
		Contour:  "v1.4.6",
		KindNode: "v1.30",
	}

	// write to script (generate it)
	err := writeVersionsScript(v, tmpSh)
	if err != nil {
		t.Fatalf("failed to generate script: %v", err)
	}
	// assert
	fsh, err := os.ReadFile(tmpSh)
	if err != nil {
		t.Fatalf("failed to read file: %v", err)
	}
	assert.Equal(t, string(fsh), expectedScript)

	// write to json
	err = writeVersionsSource(v, tmpJson)
	if err != nil {
		t.Fatalf("failed to write json: %v", err)
	}

	// assert
	fjson, err := os.ReadFile(tmpJson)
	if err != nil {
		t.Fatalf("failed to read json: %v", err)
	}
	assert.Equal(t, string(fjson), expectedJson)
}
