{ fetchFromGitLab
, pkgs
, lib
, stdenv
, makeWrapper
, python3
, nodejs-12_x
, ossOnly ? true
}:

let
  version = "1.7.1";
  suffix = lib.optionalString ossOnly "-oss";
  src' = fetchFromGitLab {
    owner = "bramw";
    repo = "baserow";
    rev = version;
    sha256 = "0jcisfhksrins33whwq46zg4r1101xvs2r0kcf1552x39r911gdg";
  };
  src = if ossOnly then pkgs.runCommand "${src'.name}${suffix}" {} ''
    cp -R ${src'} $out
    chmod -R u+w $out
    rm -rf $out/premium

    sed -i '/baserow_premium/d' $out/backend/src/baserow/config/settings/base.py
    sed -i '/premium/d' $out/web-frontend/config/nuxt.config.base.js
  '' else src';
  web-frontend-deps = import ./web-frontend {
    inherit pkgs nodejs;
    inherit (pkgs) system;
    src = "${src}/web-frontend";
  };
  mjml-tcpserver-deps = import ./mjml-tcpserver {
    inherit pkgs nodejs;
    inherit (pkgs) system;
  };

  nodejs = nodejs-12_x;
  python = python3.override {
    packageOverrides = self: super:
      let
        oss = import ./backend/pynixify/overlay.nix self super;
        premium = import ./premium-backend/pynixify/overlay.nix self super;
        baserow-premium-backend = premium.baserow-premium-backend.overridePythonAttrs (_: {
          inherit version;
          src = "${src}/premium/backend";
          postInstall = ''
            install -m0644 $src/src/baserow_premium/public_key.pem $out/${python.sitePackages}/baserow_premium/public_key.pem
          '';
        });
      in
        oss // (if !ossOnly then premium else {}) // {
          baserow-backend = oss.baserow-backend.overridePythonAttrs (oldAttrs: {
            inherit version;
            src = "${src}/backend";
            prePatch = ''
              # Yeet. Just assume everything is installed in the environment already.
              > requirements/base.txt
            '';
            propagatedBuildInputs = oldAttrs.propagatedBuildInputs ++ lib.optional (!ossOnly) baserow-premium-backend;
          });
        } // (if !ossOnly then { inherit baserow-premium-backend; } else {});
  };
in
{
  inherit src web-frontend-deps mjml-tcpserver-deps python;

  web-frontend = stdenv.mkDerivation {
    name = "baserow${suffix}-web-frontend";
    inherit src version;
    buildInputs = [ nodejs ];
    nativeBuildInputs = [ makeWrapper ];
    nodeDependencies = web-frontend-deps.shell.nodeDependencies;
    buildPhase = ''
      runHook preBuild

      outpath="$out/share/baserow"
      mkdir -p $outpath
      cp -R web-frontend $outpath/web-frontend

      ${lib.optionalString (!ossOnly) ''
        mkdir -p $outpath/premium
        cp -R premium/web-frontend $outpath/premium/web-frontend
      ''}

      # Disable prompts
      export MINIMAL=true

      pushd $outpath/web-frontend
      mkdir node_modules
      for f in $nodeDependencies/lib/node_modules/*; do
        ln -s "$f" ./node_modules
      done
      export PATH="$nodeDependencies/bin:$PATH"
      ./node_modules/nuxt/bin/nuxt.js build --config-file config/nuxt.config.local.js
      popd

      mkdir $out/bin
      makeWrapper $nodeDependencies/lib/node_modules/nuxt/bin/nuxt.js $out/bin/baserow-web-frontend \
        --run "cd $outpath/web-frontend" \
        --add-flags "start --config-file config/nuxt.config.local.js"

      runHook postBuild
    '';
    dontInstall = true;
  };

  backend = python.pkgs.baserow-backend.overridePythonAttrs (oldAttrs: {
    inherit version;
    src = "${src}/backend";
    prePatch = ''
      # Yeet. Just assume everything is installed in the environment already.
      > requirements/base.txt

      substituteInPlace src/baserow/config/settings/base.py \
        --replace 'APPLICATION_TEMPLATES_DIR = os.path.join(BASE_DIR, "../../../templates")' "APPLICATION_TEMPLATES_DIR = '$out/share/baserow/templates'"
    '';
    postInstall = ''
      comm -23 <(find $src/src/baserow/ -type d | sed "s,$src/src/baserow/,," | sort) <(find $out/${python.sitePackages}/baserow/ -type d | sed "s,$out/${python.sitePackages}/baserow/,," | sort) | while read missingDir; do
        test -e "$out/${python.sitePackages}/baserow/$missingDir" && continue
        cp -R "$src/src/baserow/$missingDir" "$out/${python.sitePackages}/baserow/$missingDir"
      done

      install -d -m 0755 $out/share/baserow
      cp -R "$src/templates" "$out/share/baserow/templates"

      install -m 0755 ${./backend/gunicorn.py} $out/bin/baserow-gunicorn
      install -m 0755 ${./backend/celery.py} $out/bin/baserow-celery
    '';
  });

  mjml-tcpserver = stdenv.mkDerivation {
    name = "mjml-tcpserver";
    inherit (python.pkgs.django-mjml) version src;

    buildInputs = [ nodejs ];
    nativeBuildInputs = [ makeWrapper ];
    nodeDependencies = mjml-tcpserver-deps.mjml;

    dontBuild = true;
    installPhase = ''
      runHook preInstall

      mkdir -p $out/bin $out/share/mjml-tcpserver
      cp mjml/node/tcpserver.js $out/share/mjml-tcpserver
      makeWrapper ${nodejs}/bin/node $out/bin/mjml-tcpserver \
        --prefix NODE_PATH : "$nodeDependencies/lib/node_modules" \
        --add-flags "$out/share/mjml-tcpserver/tcpserver.js"

      runHook postInstall
    '';
  };
}