{
  inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11";
  inputs.kicad_bom_generator = {
    url = "git+https://git.m-labs.hk/M-Labs/KiCAD_BOM_Generator.git";
    flake = false;
  };

  outputs = { self, nixpkgs, kicad_bom_generator }:
    let
      pkgs = import nixpkgs { system = "x86_64-linux"; };

      build = { variant }:
        let
          adapter_production_files = pkgs.stdenv.mkDerivation {
            name = "production-files";
            src = ./kirdy_LD_adapter_${variant};

            nativeBuildInputs = [ pkgs.kicad pkgs.zip pkgs.python3 ];

            buildPhase = ''
              echo ${variant}

              # kicad-cli requires the use of $HOME
              TMP_DIR="$(pwd)/$(mktemp -d tmp.XXXX)"
              export HOME=$TMP_DIR

              SCH=kirdy_LD_adapter_${variant}.kicad_sch
              PCB=kirdy_LD_adapter_${variant}.kicad_pcb

              # Get Revision Number from the Title Block in KiCAD Top Schematics
              REV=$(cat $SCH | grep rev | cut -d'"' -f 2)
              PREFIX=kirdy_LD_adapter_${variant}_$REV

              kicad-cli sch export python-bom $SCH -o $PREFIX"_bom".xml
              export PYTHONPATH=${pkgs.kicad.base}/share/kicad/plugins
              python ${kicad_bom_generator}/generate_bom_from_xml.py $PREFIX"_bom".xml $PREFIX"_bom".csv

              kicad-cli sch export pdf $SCH -o $PREFIX.pdf
              kicad-cli pcb export pos $PCB --format csv --units mm  -o $PREFIX"_pos".csv

              export KICAD7_3DMODEL_DIR=${pkgs.kicad.libraries.packages3d}/share/kicad/3dmodels
              kicad-cli pcb export step $PCB --subst-models --force -o $PREFIX.step

              mkdir -p $PREFIX"_gerber_drill"
              kicad-cli pcb export gerbers $PCB -l 'F.Cu,B.Cu,F.Paste,B.Paste,F.Silkscreen,B.Silkscreen,F.Mask,B.Mask,Edge.Cuts' --no-x2 --subtract-soldermask -o ./$PREFIX"_gerber_drill"

              # The additional trailing slash is due to a bug in the kicad-cli tool. https://gitlab.com/kicad/code/kicad/-/issues/14438
              kicad-cli pcb export drill $PCB -u mm --generate-map --map-format gerberx2 -o ./$PREFIX"_gerber_drill"/

              zip -r -j $PREFIX"_gerber_drill" $PREFIX"_gerber_drill"

              rm -r $TMP_DIR
            '';

            installPhase = ''
              mkdir -p $out/production_files 
              cp $PREFIX"_bom".csv $out/production_files/$PREFIX"_bom".csv
              cp $PREFIX.pdf $out/production_files/$PREFIX.pdf
              cp $PREFIX"_pos".csv $out/production_files/$PREFIX"_pos.csv"
              cp $PREFIX.step $out/production_files/$PREFIX.step
              cp $PREFIX"_gerber_drill".zip $out/production_files/$PREFIX"_gerber_drill".zip

              cp $PREFIX.step $out/production_files/$PREFIX.step
            '';
          };

          copper_plate_production_files = pkgs.stdenv.mkDerivation {
            name = "production-files";
            src = ./kirdy_LD_adapter_copper_plate;

            nativeBuildInputs = [ pkgs.kicad pkgs.zip pkgs.python3 ];

            buildPhase = ''
              # kicad-cli requires the use of $HOME
              TMP_DIR="$(pwd)/$(mktemp -d tmp.XXXX)"
              export HOME=$TMP_DIR

              PCB=kirdy_LD_adapter_copper_plate.kicad_pcb

              # Get Revision Number from the Title Block in KiCAD PCB
              REV=$(cat $PCB | grep rev | cut -d'"' -f 2)
              PREFIX=kirdy_LD_adapter_copper_plate_$REV

              export KICAD7_3DMODEL_DIR=${pkgs.kicad.libraries.packages3d}/share/kicad/3dmodels
              kicad-cli pcb export step $PCB --subst-models --force -o $PREFIX.step

              rm -r $TMP_DIR
            '';

            installPhase = ''
              mkdir -p $out/production_files 
              cp $PREFIX.step $out/production_files/$PREFIX.step
            '';
          };

        in {
          "LD_adapter_${variant}_PCB" = adapter_production_files;
          "LD_adapter_${variant}_copper_plate" = copper_plate_production_files;
        };

    in rec {
      formatter.x86_64-linux = nixpkgs.legacyPackages.x86_64-linux.nixfmt;

      packages.x86_64-linux = (build { variant = "type_1"; })
        // (build { variant = "type_2"; });

      devShells.x86_64-linux.default =
        let pkgs = nixpkgs.legacyPackages.x86_64-linux;
        in pkgs.mkShell {
          name = "kicad-dev-shell";
          buildInputs = [ pkgs.kicad ];
        };
    };
}
