package photoprism

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

	"github.com/stretchr/testify/assert"

	"github.com/photoprism/photoprism/internal/config"
	"github.com/photoprism/photoprism/pkg/fs"
)

func TestConvert_ToImage(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping test in short mode.")
	}

	cnf := config.TestConfig()
	initErr := cnf.InitializeTestData()
	assert.NoError(t, initErr)
	convert := NewConvert(cnf)

	t.Run("Video", func(t *testing.T) {
		fileName := filepath.Join(cnf.ExamplesPath(), "gopher-video.mp4")
		outputName := filepath.Join(cnf.SidecarPath(), cnf.ExamplesPath(), "gopher-video.mp4.jpg")

		_ = os.Remove(outputName)

		assert.Truef(t, fs.FileExists(fileName), "input file does not exist: %s", fileName)

		mf, err := NewMediaFile(fileName)

		if err != nil {
			t.Fatal(err)
		}

		img, err := convert.ToImage(mf, false)

		if err != nil {
			t.Fatal(err)
		}

		assert.Equal(t, img.FileName(), outputName)
		assert.Truef(t, fs.FileExists(img.FileName()), "output file does not exist: %s", img.FileName())

		t.Logf("video metadata: %+v", img.MetaData())

		_ = os.Remove(outputName)
	})
	t.Run("Raw", func(t *testing.T) {
		jpegFilename := filepath.Join(cnf.ImportPath(), "fern_green.jpg")

		assert.Truef(t, fs.FileExists(jpegFilename), "file does not exist: %s", jpegFilename)

		t.Logf("Testing RAW to JPEG convert with %s", jpegFilename)

		mf, err := NewMediaFile(jpegFilename)

		if err != nil {
			t.Fatal(err)
		}

		imageJpeg, err := convert.ToImage(mf, false)

		if err != nil {
			t.Fatal(err)
		}

		infoJpeg := imageJpeg.MetaData()

		assert.Equal(t, jpegFilename, imageJpeg.fileName)

		assert.Equal(t, "Canon EOS 7D", infoJpeg.CameraModel)

		rawFilename := filepath.Join(cnf.ImportPath(), "raw", "IMG_2567.CR2")
		jpgFilename := filepath.Join(cnf.SidecarPath(), cnf.ImportPath(), "raw/IMG_2567.CR2.jpg")

		t.Logf("Testing RAW to JPEG convert with %s", rawFilename)

		rawMediaFile, err := NewMediaFile(rawFilename)

		if err != nil {
			t.Fatalf("%s for %s", err.Error(), rawFilename)
		}

		imageRaw, err := convert.ToImage(rawMediaFile, false)

		if err != nil {
			t.Fatalf("%s for %s", err.Error(), rawFilename)
		}

		assert.True(t, fs.FileExists(jpgFilename), "Primary file was not found - is Darktable installed?")

		if imageRaw == nil {
			t.Fatal("imageRaw is nil")
		}

		assert.NotEqual(t, rawFilename, imageRaw.fileName)

		infoRaw := imageRaw.MetaData()

		assert.Equal(t, "Canon EOS 6D", infoRaw.CameraModel)

		_ = os.Remove(jpgFilename)
	})
	t.Run("Svg", func(t *testing.T) {
		svgFile := fs.Abs("./testdata/agpl.svg")

		mediaFile, err := NewMediaFile(svgFile)

		t.Logf("svg: %s", mediaFile.FileName())

		if err != nil {
			t.Fatal(err)
		}

		imageFile, err := convert.ToImage(mediaFile, false)

		if err != nil {
			t.Fatal(err)
		}

		t.Logf("jpeg: %s", imageFile.FileName())

		_ = imageFile.Remove()
	})
	t.Run("SvgWithVectorsDisabled", func(t *testing.T) {
		svgFile := fs.Abs("./testdata/agpl.svg")

		cnf.Options().DisableVectors = true

		mediaFile, err := NewMediaFile(svgFile)

		t.Logf("svg: %s", mediaFile.FileName())

		if err != nil {
			t.Fatal(err)
		}

		imageFile, err := convert.ToImage(mediaFile, false)

		if err == nil {
			t.Fatal("error expected")
		}

		assert.Nil(t, imageFile)

		cnf.Options().DisableVectors = false

	})
	t.Run("Webp", func(t *testing.T) {
		webpFile := fs.Abs("./testdata/windows95.webp")

		mediaFile, err := NewMediaFile(webpFile)

		t.Logf("webp: %s", mediaFile.FileName())

		if err != nil {
			t.Fatal(err)
		}

		imageFile, err := convert.ToImage(mediaFile, false)

		if err != nil {
			t.Fatal(err)
		}

		t.Logf("jpeg: %s", imageFile.FileName())

		_ = imageFile.Remove()
	})
	t.Run("DoNotConvertThumb", func(t *testing.T) {
		thumbFile := fs.Abs("./testdata/animated-earth.thm")

		mediaFile, err := NewMediaFile(thumbFile)

		t.Logf("svg: %s", mediaFile.FileName())

		if err != nil {
			t.Fatal(err)
		}

		imageFile, err := convert.ToImage(mediaFile, false)

		if err == nil {
			t.Fatal("error expected")
		}

		assert.Nil(t, imageFile)
	})
}

func TestConvert_PngConvertCmds(t *testing.T) {
	cnf := config.TestConfig()
	convert := NewConvert(cnf)

	t.Run("SVG", func(t *testing.T) {
		svgFile := fs.Abs("./testdata/agpl.svg")
		pngFile := fs.Abs("./testdata/agpl.png")

		mediaFile, err := NewMediaFile(svgFile)

		t.Logf("svg: %s", mediaFile.FileName())

		if err != nil {
			t.Fatal(err)
		}

		cmds, useMutex, err := convert.PngConvertCmds(mediaFile, pngFile)

		if err != nil {
			t.Fatal(err)
		}

		assert.False(t, useMutex)

		assert.NotEmpty(t, cmds)
		assert.True(t, strings.Contains(cmds[0].String(), "rsvg"))

		t.Logf("commands: %#v", cmds)
	})
}
