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 want to add/modify these components, please read the how-to steps in
# ./cmd/components/main.go.
# You can regenerate with "make hack-generate-components".

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.32.0@sha256:c48c62eac5da28cdadcf560d1d8616cfa6783b58f0d94cf63ad1bf49600cb027

	# find source-of-truth in component-versions.json to add/modify components
	knative_serving_version="v1.19.0"
	knative_eventing_version="v1.19.0"
	contour_version="v1.19.0"
	tekton_version="v1.1.0"
	pac_version="v0.35.2"
}
`

const expectedJson string = `{
	"Contour": {
		"version": "v1.19.0",
		"owner": "knative-extensions",
		"repo": "net-contour"
	},
	"Eventing": {
		"version": "v1.19.0",
		"owner": "knative",
		"repo": "eventing"
	},
	"KindNode": {
		"version": "v1.32.0@sha256:c48c62eac5da28cdadcf560d1d8616cfa6783b58f0d94cf63ad1bf49600cb027"
	},
	"Pac": {
		"version": "v0.35.2"
	},
	"Serving": {
		"version": "v1.19.0",
		"owner": "knative",
		"repo": "serving"
	},
	"Tekton": {
		"version": "v1.1.0"
	}
}
`

// TestRead should just successfully unmarshal
func TestRead(t *testing.T) {
	dir := t.TempDir()

	// just assign this for simplicity, no need to the same variable twice
	const jsonContent = expectedJson

	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")

	// as if we just unmarshalled this
	c := ComponentList{
		"Contour": &Component{
			Version: "v1.19.0",
			Owner:   "knative-extensions",
			Repo:    "net-contour",
		},
		"Eventing": {
			Version: "v1.19.0",
			Owner:   "knative",
			Repo:    "eventing",
		},
		"KindNode": {
			Version: "v1.32.0@sha256:c48c62eac5da28cdadcf560d1d8616cfa6783b58f0d94cf63ad1bf49600cb027",
		},
		"Pac": {
			Version: "v0.35.2",
		},
		"Serving": {
			Version: "v1.19.0",
			Owner:   "knative",
			Repo:    "serving",
		},
		"Tekton": {
			Version: "v1.1.0",
		},
	}

	// write to script (generate it)
	err := writeScript(c, 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 = writeSource(c, 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)
}
