package pkg

import (
	"fmt"
	"path/filepath"
	"strings"
	"testing"

	"gitlab.com/M0M097/pkg/lib/sboRepo"
	"gitlab.com/M0M097/pkg/lib/utils"
)

const (
	DUMMY_PKG1                  = "pkg1"
	DUMMY_PKG2                  = "pkg2"
	DUMMY_PKG3                  = "pkg3"
	DUMMY_PKG3_DOWNLOAD         = "foo.tar.gz"
	DUMMY_VERSION               = "1.0"
	DUMMY_BLACKLISTED_PKG       = "blacklisted_pkg"
	DUMMY_GREYLISTED_PKG        = "greylisted_pkg"
	DUMMY_OTHER_BLACKLISTED_PKG = "other_blacklisted_pkg"
	MOCK_PKG_SLACKBUILD_CONTENT = "exit 1"
	MOCK_PKG_README_CONTENT     = "README file\n"
	MOCK_PKG_SLACK_DES_CONTENT  = `# HOW TO EDIT THIS FILE:
# The \"handy ruler\" below makes it easier to edit a package description.  Line
# up the first '|' above the ':' following the base package name, and the '|'
# on the right side marks the last column you can put a character in.  You must
# make exactly 11 lines for the formatting to be correct.  It's also
# customary to leave one space after the ':'.

      |-----handy-ruler------------------------------------------------------|
name: name Description
name:
name:
name:
name:
name:
name:
name:
name:
name:
name:
`
)

var dummyPkg3 = sboRepo.NewPackage(DUMMY_PKG3, "")

func makeDummyRepo(t *testing.T) (string, string) {
	t.Helper()
	repo := t.TempDir()
	tmpDir := t.TempDir()

	pkgCreator := sboRepo.PkgCreator{
		Name:              DUMMY_PKG1,
		Path:              filepath.Join(repo, "category1"),
		Version:           DUMMY_VERSION,
		Requires:          DUMMY_PKG2,
		SlackBuildContent: MOCK_PKG_SLACKBUILD_CONTENT,
		ReadmeContent:     MOCK_PKG_README_CONTENT,
		SlackDescContent:  MOCK_PKG_SLACK_DES_CONTENT,
	}
	pkgCreator.Create()

	pkgCreator.Path = filepath.Join(repo, "category2")
	pkgCreator.Requires = ""
	for _, pkg := range []string{DUMMY_PKG2, DUMMY_BLACKLISTED_PKG,
		DUMMY_GREYLISTED_PKG, DUMMY_OTHER_BLACKLISTED_PKG} {
		pkgCreator.Name = pkg
		pkgCreator.Create()
	}

	pkgCreator.Name = DUMMY_PKG3
	pkgCreator.Download = DUMMY_PKG3_DOWNLOAD
	pkgCreator.Md5sum = "d41d8cd98f00b204e9800998ecf8427e" // empty file

	dummyPkg3 = *pkgCreator.Create()

	utils.Content2File(dummyPkg3.SlackBuild(), "#!/bin/sh\necho building "+DUMMY_PKG3)
	utils.Content2File(filepath.Join(tmpDir, fmt.Sprintf("%s-%s-%s-1_SBo.txz", DUMMY_PKG3, DUMMY_VERSION, "noarch")), "")
	return repo, tmpDir
}

func createPkgTestfiles(p *sboRepo.Package, t *testing.T) {
	*p = *sboRepo.PkgCreator{
		Name:              p.Name(),
		Path:              t.TempDir(),
		Version:           DUMMY_VERSION,
		Download:          DUMMY_PKG3_DOWNLOAD,
		Md5sum:            "d41d8cd98f00b204e9800998ecf8427e",
		SlackBuildContent: MOCK_PKG_SLACKBUILD_CONTENT,
		ReadmeContent:     MOCK_PKG_README_CONTENT,
		SlackDescContent:  MOCK_PKG_SLACK_DES_CONTENT,
	}.Create()
}

func mustBeEqual(t *testing.T, got, expected interface{}) {
	t.Helper()
	if got != expected {
		t.Fatalf("Expected '%v', got '%v'", expected, got)
	}
}

func mustBeEqualStringSlices(t *testing.T, got, expected []string) {
	t.Helper()
	if len(got) != len(expected) {
		t.Fatalf("Expected %v and %v to have the same length, got %d and %d",
			expected, got, len(expected), len(got))
	}
	for i := range got {
		mustBeEqual(t, got[i], expected[i])
	}
}

func mustContain(t *testing.T, output string, expected ...string) {
	t.Helper()
	for _, s := range expected {
		if !strings.Contains(output, s) {
			t.Errorf("Expected %v to be in %v", s, output)
		}
	}
}

func mustNotContain(t *testing.T, output string, expected ...string) {
	t.Helper()
	for _, s := range expected {
		if strings.Contains(output, s) {
			t.Errorf("Expected %v not to be in %v", s, output)
		}
	}
}
