{ depot
, pkgs ? import <nixpkgs> {}
, lib ? pkgs.lib
, ... }:

let
  heatshrink2 = pm: pm.buildPythonPackage rec {
    pname = "heatshrink2";
    version = "0.13.0";

    src = pkgs.fetchFromGitHub {
      owner = "eerimoq";
      repo = "pyheatshrink";
      rev = version;
      hash = "sha256:13hvzmp58vinwb77ijssr6bd35bisnl78n0n3azyvibjf5vlrjl2";
      fetchSubmodules = true;
    };

    propagatedBuildInputs = with pm; [
      cython
    ];
  };
  scons = pkgs.scons.overridePythonAttrs (_: rec {
    version = "4.4.0";
    src = pkgs.fetchFromGitHub {
      owner = "Scons";
      repo = "scons";
      rev = version;
      sha256 = "sha256:1czswx1fj2j48rspkrvarkr43k0vii9rsmz054c9yby1dq362fgr";
    };
  });
  oslex = pm: pm.buildPythonPackage rec {
    pname = "oslex";
    version = "0.1.3";
    pyproject = true;

    src = pkgs.fetchFromGitHub {
      owner = "petamas";
      repo = "oslex";
      rev = "release/v${version}";
      hash = "sha256-OcmBtxGS1Cq2kEcxF0Il62LUGbAAcG4lieokr/nK2/4=";
    };

    nativeBuildInputs = with pm; [
      hatchling
      pythonRelaxDepsHook
    ];

    pythonRemoveDeps = true;

    postPatch = ''
      substituteInPlace pyproject.toml \
        --replace-fail '"mslex",' ""
    '';
  };
  cxxheaderparser = pm: pm.buildPythonPackage rec {
    pname = "cxxheaderparser";
    version = "1.3.4";

    src = pkgs.fetchFromGitHub {
      owner = "robotpy";
      repo = "cxxheaderparser";
      rev = version;
      hash = "sha256-Cyo+18mH1p5Zy4dWP3mjZRIkZZOyb61ABedk/amDi0g=";
    };

    postPatch = ''
      echo '__version__ = "${version}"' > cxxheaderparser/version.py
    '';
  };
  python-with-deps = pkgs.python3.withPackages (pm: with pm; [
    pillow
    (heatshrink2 pm)
    protobuf
    setuptools
    pyserial
    protobuf
    (pm.toPythonModule scons)
    (oslex pm)
    (cxxheaderparser pm)
    ansi
    colorlog
    pyelftools
  ]);
  deps = with pkgs; [
    gcc-arm-embedded-12
    openocd
    clang
    dfu-util
    git
    protobuf
    python-with-deps
  ];

  versionData = builtins.fromJSON (builtins.readFile ./version.json);
in
pkgs.stdenvNoCC.mkDerivation rec {
  pname = "flipper-firmware";
  inherit (versionData) version upstreamVersion;

  src = pkgs.fetchgit {
    inherit (versionData.src) url rev sha256 fetchLFS fetchSubmodules deepClone leaveDotGit;
  };

  patches = [
    ./0001-simply-do-not-run-git.patch
    ./0002-proto_ver_generator-use-changelog-not-git.patch
    ./0003-scripts-fbt-version-no-git.patch
    ./0004-scripts-sconsdist-disable-strict_timestamps-allow-FS.patch
    ./0005-pass-SOURCE_DATE_EPOCH-to-tooling.patch
  ];

  nativeBuildInputs = deps;

  WORKFLOW_BRANCH_OR_TAG = version;
  DIST_SUFFIX = "";
  CUSTOM_FLIPPER_NAME = "";

  FBT_NOENV = 1;
  FBT_NO_SYNC = 1;
  buildPhase = ''
    runHook preBuild

    mkdir -p $NIX_BUILD_TOP/bin
    ln -s $(command -v arm-none-eabi-gcc) $NIX_BUILD_TOP/bin/arm-none-eabi-cc
    ln -s $(command -v arm-none-eabi-gdb) $NIX_BUILD_TOP/bin/arm-none-eabi-gdb-py3
    export PATH=$NIX_BUILD_TOP/bin:$PATH
    export WORKFLOW_BRANCH_OR_TAG DIST_SUFFIX CUSTOM_FLIPPER_NAME

    echo building icons
    ./fbt icons
    echo building resources
    ./fbt -j$NIX_BUILD_CORES COMPACT=1 DEBUG=0 resources icons
    echo building firmware
    ./fbt -j$NIX_BUILD_CORES --with-updater COMPACT=1 DEBUG=0 updater_package

    runHook postBuild
  '';

  installPhase = ''
    runHook preInstall

    cp -r dist $out

    runHook postInstall
  '';

  passthru.deps = deps;
  passthru.upload = let
    firmware = depot.nix.pkgs.flipperzero-firmware;
  in pkgs.writeShellApplication {
    name = "upload-f0";
    runtimeInputs = [ pkgs.google-cloud-sdk pkgs.vault ];
    text = ''
      vault_path=unix:///run/tokend/sock

      if [[ "$(groups)" =~ (.* |^)"users"($| .*) ]] || ! test -f /etc/NIXOS; then
        vault_path=https://vault.int.lukegb.com
      fi

      echo "Fetching token from Vault at $vault_path..."
      token="$(vault read --field=token --address="$vault_path" gcp/roleset/lukegbcom-deployer/token)"
      export CLOUDSDK_AUTH_ACCESS_TOKEN="$token"

      echo "Uploading ${firmware.version}"
      gcloud storage cp "${firmware}/f7-C/*-update-*.tgz" "gs://lukegb-flipperzero/${firmware.name}.tgz"
    '';
  };
}