package configloader

import (
    "testing"
    "os"
    "path/filepath"
)

// Returns a generally valid config. Single values can then be
// replaced with the actually tested contents.
func getTestConfig() MDWebDavUploaderConfig {

    input := MDWebDavUploaderConfig{}
    input.InstanceLink = "https://hessen.museum-digital.de/home"
    input.Mail = "test@example.com"
    input.InstitutionId = 1;
    input.Parser = "Lido"

    tmpDir := os.TempDir()
    testDir := filepath.Join(tmpDir, "/existing-dir-for-import")
    mkdirErr := os.MkdirAll(testDir, os.ModePerm)
    if mkdirErr != nil {
        panic("Test failure: Failed to create test dir")
    }

    input.MetadataFolder = testDir
    input.MediaFolder = testDir

    return input


}

// Test that ValidateConfig() fails on non-URLs.
func TestValidateUploaderConfigFailsOnInvalidInstanceUrl(t *testing.T) {

    input := getTestConfig()
    input.InstanceLink = "abcmuseum-digital.org"
    _, err := ValidateConfig(input)
    if err == nil {
        t.Fatalf("ValidateConfig() does not return an error on a non-URL (via ValidateInstanceLink)")
    }

}

// Test that ValidateConfig cleans an instance URL as per ValidateInstanceLink().
func TestValidateUploaderConfigCleansInstanceViaValidateInstanceLink(t *testing.T) {

    input := getTestConfig()
    input.InstanceLink = "https://hessen.museum-digital.de/home"
    returnVal, _ := ValidateConfig(input)
    if returnVal.InstanceLink != "https://hessen.museum-digital.de" {
        t.Fatalf("Failed to clean up input URL")
    }

}

// Test that ValidateConfig() fails on invalid mail.
func TestValidateUploaderConfigFailsOnInvalidMail(t *testing.T) {

    input := getTestConfig()
    input.Mail = "test"
    _, err := ValidateConfig(input)
    if err == nil {
        t.Fatalf("ValidateConfig() does not return an error on a mail address")
    }

}

// Test that ValidateConfig() accepts a valid mail address.
func TestValidateUploaderConfigAcceptsValidMail(t *testing.T) {

    input := getTestConfig()
    input.Mail = "test@example.com"
    returnVal, _ := ValidateConfig(input)
    if returnVal.Mail != "test@example.com" {
        t.Fatalf("Failed to accept valid mail")
    }

}

// Test that ValidateConfig() fails on negative / invalid IDs.
func TestValidateUploaderConfigFailsOnInvalidInstitutionId(t *testing.T) {

    input := getTestConfig()
    input.InstitutionId = -1
    _, err := ValidateConfig(input)
    if err == nil {
        t.Fatalf("ValidateConfig() does not return an error on an invalid institution ID")
    }

}

// Test that ValidateConfig() accepts valid institution IDs.
func TestValidateUploaderConfigAcceptsValidInstitutionId(t *testing.T) {

    input := getTestConfig()
    input.InstitutionId = 1
    returnVal, _ := ValidateConfig(input)
    if returnVal.InstitutionId != 1 {
        t.Fatalf("Failed to accept valid institution ID")
    }

}

// Test that ValidateConfig() fails on negative / invalid IDs.
func TestValidateUploaderConfigFailsOnInvalidParser(t *testing.T) {

    input := getTestConfig()
    input.Parser = "nonexistentparser"
    _, err := ValidateConfig(input)
    if err == nil {
        t.Fatalf("ValidateConfig() does not return an error on an invalid parser")
    }

}

// Test that ValidateConfig() accepts valid ParserDs.
func TestValidateUploaderConfigAcceptsValidParser(t *testing.T) {

    input := getTestConfig()
    input.Parser = "ParserLido"
    returnVal, _ := ValidateConfig(input)
    if returnVal.Parser != "Lido" {
        t.Fatalf("Failed to accept and clean valid parser")
    }

}

// Test that ValidateConfig() fails on non-existent folder.
func TestValidateUploaderConfigFailsOnInvalidMetadataFolder(t *testing.T) {

    input := getTestConfig()
    input.MetadataFolder = "nonexistentfolder"
    _, err := ValidateConfig(input)
    if err == nil {
        t.Fatalf("ValidateConfig() does not return an error on an invalid metadata folder")
    }

}

// Test that saving and reading config works.
func TestWritingAndReadingConfigWorks(t *testing.T) {

    input := getTestConfig()
    input, _ = ValidateConfig(input)

    writeErr := StoreConfigToFile(input, input.MetadataFolder + "/config.json")
    if writeErr != nil {
        t.Log("Error:")
        t.Log(writeErr)
        t.Fatalf("Failed to write config to override path")
    }

    loadedFromFile, setupRequired, err := LoadFromFile(input.MetadataFolder + "/config.json")

    if setupRequired != false {
        t.Fatalf("Expected no setup to be required, but return value indicated thus")
    }
    if err != nil {
        t.Fatalf("Returned an error on trying to load config file")
    }
    // Golang can't compare structs with slices or maps
    if input.InstanceLink != loadedFromFile.InstanceLink || input.Mail != loadedFromFile.Mail || input.WebDavAuthToken != loadedFromFile.WebDavAuthToken || input.InstitutionId != loadedFromFile.InstitutionId || input.Parser != loadedFromFile.Parser || input.MetadataFolder != loadedFromFile.MetadataFolder || input.MediaFolder != loadedFromFile.MediaFolder || input.PublishOnImport != loadedFromFile.PublishOnImport {
        t.Log("Input")
        t.Log(input)

        t.Log("Loaded output")
        t.Log(loadedFromFile)

        t.Fatalf("Failed to write and then load the same config")
    }

}
