{ lib, ... }:
let
  ocrContent = "Music Test";
  musicFile = "test.mp3";

  ocrPauseColor = "#FF00FF";
  ocrStartColor = "#00FFFF";
in
{
  name = "lomiri-music-app-standalone";
  meta = {
    maintainers = lib.teams.lomiri.members;
    # This needs a Linux VM
    platforms = lib.platforms.linux;
  };

  nodes.machine =
    { config, pkgs, ... }:
    {
      imports = [
        ./common/auto.nix
        ./common/user-account.nix
        ./common/x11.nix
      ];

      services.xserver.enable = true;

      environment = {
        # Setup video
        etc."${musicFile}".source =
          pkgs.runCommand musicFile
            {
              nativeBuildInputs = with pkgs; [
                ffmpeg # produce music
                (imagemagick.override { ghostscriptSupport = true; }) # produce OCR-able cover image
              ];
            }
            ''
              magick -size 400x400 canvas:white -pointsize 40 -fill black -annotate +100+100 '${ocrContent}' output.png
              ffmpeg -re \
                -f lavfi -i anullsrc=channel_layout=mono:sample_rate=44100 \
                -i output.png \
                -map 0:0 -map 1:0 \
                -id3v2_version 3 \
                -metadata:s:v title="Album cover" \
                -metadata:s:v comment="Cover (front)" \
                -t 120 \
                $out -loglevel fatal
            '';

        systemPackages =
          with pkgs;
          [
            xdg-user-dirs # generate XDG dirs
            xdotool # mouse movement
          ]
          ++ (with pkgs.lomiri; [
            mediascanner2
            lomiri-music-app
            lomiri-thumbnailer
            # To check if playback actually works, or is broken due to missing codecs, we need to make the app's icons more OCR-able
            (lib.meta.hiPrio (
              suru-icon-theme.overrideAttrs (oa: {
                # Colour the background in special colours, which we can OCR for
                postPatch =
                  (oa.postPatch or "")
                  + ''
                    substituteInPlace suru/actions/scalable/media-playback-pause.svg \
                      --replace-fail 'fill:none' 'fill:${ocrPauseColor}'

                    substituteInPlace suru/actions/scalable/media-playback-start.svg \
                      --replace-fail 'fill:none' 'fill:${ocrStartColor}'
                  '';
              })
            ))
          ]);

        variables = {
          UITK_ICON_THEME = "suru";
        };
      };

      # Get mediascanner-2.0.service
      services.desktopManager.lomiri.enable = lib.mkForce true;

      # ...but stick with icewm
      services.displayManager.defaultSession = lib.mkForce "none+icewm";

      systemd.tmpfiles.settings = {
        "10-lomiri-music-app-test-setup" = {
          "/root/Music".d = {
            mode = "0755";
            user = "root";
            group = "root";
          };
          "/root/Music/${musicFile}"."C+".argument = "/etc/${musicFile}";
        };
      };

      i18n.supportedLocales = [ "all" ];
    };

  enableOCR = true;

  testScript = ''
    from collections.abc import Callable
    import tempfile
    import subprocess

    pauseColor: str = "${ocrPauseColor}"
    startColor: str = "${ocrStartColor}"

    # Based on terminal-emulators.nix' check_for_pink
    def check_for_color(color: str) -> Callable[[bool], bool]:
        def check_for_color_retry(final=False) -> bool:
            with tempfile.NamedTemporaryFile() as tmpin:
                machine.send_monitor_command("screendump {}".format(tmpin.name))

                cmd = 'convert {} -define histogram:unique-colors=true -format "%c" histogram:info:'.format(
                    tmpin.name
                )
                ret = subprocess.run(cmd, shell=True, capture_output=True)
                if ret.returncode != 0:
                    raise Exception(
                        "image analysis failed with exit code {}".format(ret.returncode)
                    )

                text = ret.stdout.decode("utf-8")
                return color in text

        return check_for_color_retry

    machine.wait_for_x()

    # mediascanner2 needs XDG dirs to exist
    machine.succeed("xdg-user-dirs-update")

    # mediascanner2 needs to have run, is only started automatically by Lomiri
    machine.systemctl("start mediascanner-2.0.service", "root")

    with subtest("lomiri music launches"):
        machine.succeed("lomiri-music-app >&2 &")
        machine.wait_for_text("favorite music")
        machine.send_key("alt-f10")
        machine.screenshot("lomiri-music")

    with subtest("lomiri music plays music"):
        machine.succeed("xdotool mousemove 30 720 click 1") # Skip intro
        machine.wait_for_text("Albums")
        machine.succeed("xdotool mousemove 25 45 click 1") # Open categories
        machine.wait_for_text("Tracks")
        machine.succeed("xdotool mousemove 25 240 click 1") # Switch to Tracks category
        machine.wait_for_text("test") # the test file
        machine.screenshot("lomiri-music_listing")

        # Ensure pause colours isn't present already
        assert (
            check_for_color(pauseColor)(True) == False
        ), "pauseColor {} was present on the screen before we selected anything!".format(pauseColor)

        machine.succeed("xdotool mousemove 25 120 click 1") # Select the track

        # Waiting for pause icon to be displayed
        with machine.nested("Waiting for the screen to have pauseColor {} on it:".format(pauseColor)):
            retry(check_for_color(pauseColor))

        machine.screenshot("lomiri-music_playback")

        # Ensure play colours isn't present already
        assert (
            check_for_color(startColor)(True) == False
        ), "startColor {} was present on the screen before we were expecting it to be!".format(startColor)

        machine.succeed("xdotool mousemove 860 480 click 1") # Pause track (only works if app can actually decode the file)

        # Waiting for play icon to be displayed
        with machine.nested("Waiting for the screen to have startColor {} on it:".format(startColor)):
            retry(check_for_color(startColor))

        machine.screenshot("lomiri-music_paused")

        # Lastly, check if generated cover image got extracted properly
        # if not, indicates an issue with mediascanner / lomiri-thumbnailer
        machine.wait_for_text("${ocrContent}")

    machine.succeed("pkill -f lomiri-music-app")

    with subtest("lomiri music localisation works"):
        machine.succeed("env LANG=de_DE.UTF-8 lomiri-music-app .mp4 >&2 &")
        machine.wait_for_text("Titel")
        machine.screenshot("lomiri-music_localised")
  '';
}