{ config, pkgs, ... }:
let
  my-python-packages = python-packages: with python-packages; [
    appdirs
    requests
    virtualenv
    ipython
    ipdb
    virtualenvwrapper
    pip
  ];
  python-with-my-packages = pkgs.python3.withPackages my-python-packages;
  udiskie-appindicator = pkgs.udiskie.overrideAttrs (oldAttrs: rec {
    version = "1.7.5";
    src = pkgs.fetchFromGitHub {
      owner = "coldfix";
      repo = "udiskie";
      rev = version;
      sha256 = "1mcdn8ha5d5nsmrzk6xnnsqrmk94rdrzym9sqm38zk5r8gpyl1k4";
    };
    propagatedBuildInputs = oldAttrs.propagatedBuildInputs ++ [pkgs.libappindicator-gtk3];
  });
  clipit-master = pkgs.clipit.overrideAttrs (oldAttrs: rec {
    version = "50d983514386029a1f133187902084b753458f32";
    preConfigure = "./autogen.sh";
    configureFlags = ["--with-gtk3" "--enable-appindicator"];
    src = pkgs.fetchFromGitHub {
      owner = "IvanMalison";
      repo = "ClipIt";
      sha256 = "1d52zjnxmcp2kr4wvq2yn9fhr61v9scp91fxfvasvz5m7k1zagdn";
      rev = version;
    };
    buildInputs = with pkgs; [
      autoconf automake intltool gtk3 xdotool hicolor-icon-theme
      libappindicator-gtk3
    ];
  });
  git-sync = with pkgs; stdenv.mkDerivation rec {
    name = "git-sync-${version}";
    version = "20151024";

    src = fetchFromGitHub {
      owner = "simonthum";
      repo = "git-sync";
      rev = "eb9adaf2b5fd65aac1e83d6544b9076aae6af5b7";
      sha256 = "01if8y93wa0mwbkzkzx2v1vqh47zlz4k1dysl6yh5rmppd1psknz";
    };

    buildInputs = [ makeWrapper ];

    dontBuild = true;

    installPhase = ''
      mkdir -p $out/bin
      cp -a git-sync $out/bin/git-sync
    '';

    wrapperPath = with stdenv.lib; makeBinPath [
      coreutils
      git
      gnugrep
      gnused
    ];

    fixupPhase = ''
      patchShebangs $out/bin

      wrapProgram $out/bin/git-sync \
        --prefix PATH : "${wrapperPath}"
      '';
  };
  pasystray-appindicator = with pkgs; pasystray.overrideAttrs (oldAttrs: rec {
    buildInputs = oldAttrs.buildInputs ++ [libappindicator-gtk3];
  });
in
{
  nixpkgs.config.allowUnfree = true;
  security.sudo.wheelNeedsPassword = false;
  networking.networkmanager.enable = true;
  networking.firewall.enable = false;

  i18n = {
    consoleKeyMap = "us";
    defaultLocale = "en_US.UTF-8";
  };

  # Set your time zone.
  # TODO: this should be set dynamically
  time.timeZone = "America/Los_Angeles";

  fonts = {
    fonts = with pkgs; [
      dejavu_fonts
      emojione
      fira-mono
      font-awesome-ttf
      noto-fonts-emoji
      roboto
      source-code-pro
      source-sans-pro
      source-serif-pro
      twemoji-color-font
    ];
    fontconfig = {
      defaultFonts = {
        monospace = [ "Source Code Pro" ];
        sansSerif = [ "Roboto" ];
        serif     = [ "Source Serif Pro" ];
      };
      ultimate = {
        enable = false;
      };
    };
  };

  # List packages installed in system profile. To search, run:
  # $ nix search wget
  environment.systemPackages = with pkgs; [

    # Applications
    calibre
    discord
    emacs
    firefox
    kleopatra
    google-chrome
    hexchat
    keybase-gui
    kodi
    lxappearance
    rxvt_unicode
    spotify
    termite
    vlc
    xfce.thunar

    # Appearance
    numix-icon-theme-circle
    gnome3.adwaita-icon-theme
    hicolor-icon-theme
    plasma5.breeze-gtk
    plasma5.breeze-qt5
    gnome-breeze

    # Desktop
    # haskellPackages.status-notifier-item
    autorandr
    clipit-master
    compton
    feh
    gnome3.gpaste
    kdeconnect
    libnotify
    lxqt.lxqt-powermanagement
    networkmanagerapplet
    notify-osd
    pasystray-appindicator
    pinentry
    pommed_light
    rofi
    rofi-pass
    skippy-xd
    synergy
    udiskie-appindicator
    volnoti
    xclip
    xdotool
    xorg.xkbcomp
    xsettingsd

    # Audio
    pulsemixer
    pavucontrol
    playerctl

    # Haskell
    cabal-install
    cabal2nix
    ghc
    stack2nix
    stack

    # Tools
    binutils
    dfeet
    gcc
    gdb
    gitFull
    git-sync
    gnumake
    gnupg
    htop
    inotify-tools
    ispell
    ncdu
    neofetch
    pass
    plasma-workspace
    powertop
    python-with-my-packages
    qt5.qttools
    rcm
    scrot
    silver-searcher
    stow
    tmux
    valgrind
    wget
    wmctrl
    zsh

    # Nix
    nix-prefetch-git

    # Miscellaneous
    android-udev-rules
    librsvg
    transmission-gtk
  ];

  environment.variables = {
    GDK_PIXBUF_MODULE_FILE = "${pkgs.librsvg.out}/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache";
  };

  programs.gnupg.agent = { enable = true; enableSSHSupport = true; };
  # Enabling zsh will clobber path because of the way it sets up /etc/zshenv
  # programs.zsh.enable = true;
  # Instead we just make sure to source profile from zsh
  environment.etc."zshenv".text =
    ''
      if [ -n "$__ETC_PROFILE_DONE" ]; then return; fi
      source /etc/profile
    '';
  services.openssh.enable = true;
  services.avahi = {
    enable = true;
    nssmdns = true;
    publish = {
      enable = true;
      domain = true;
      userServices = true;
    };
  };
  sound.enable = true;
  hardware.pulseaudio.enable = true;

  services.xserver = {
    exportConfiguration = true;
    enable = true;
    layout = "us";
    desktopManager = {
      gnome3.enable = true;
      default = "none";
    };
    windowManager = {
      default = "xmonad";
      i3.enable = true;
      session = [{
        name = "xmonad";
        start = ''
          /usr/bin/env imalison-xmonad &
          waitPID=$!
        '';
      }];
    };
    displayManager = {
      # lightdm = {
      #   enable = true;
      #   extraSeatDefaults=''
      #     greeter-hide-users=false
      #   '';
      # };
      sddm = {
        enable = true;
      };
      sessionCommands = ''
        systemctl --user import-environment GDK_PIXBUF_MODULE_FILE
      '';
    };

  };

  hardware.opengl.driSupport32Bit = true;

  # Define a user account. Don't forget to set a password with ‘passwd’.
  users.extraUsers = let
    extraGroups = [
      "wheel" "disk" "audio" "video"
      "networkmanager" "systemd-journal"
    ];
    userDefaults = {
      inherit extraGroups;
      group = "users";
      isNormalUser = true;
      createHome = true;
      shell = pkgs.zsh;
    };
  in {
    imalison = userDefaults // {
      name = "imalison";
      uid = 1000;
      home = "/home/imalison";
      shell = pkgs.zsh;
    };
    kat = userDefaults // {
      name = "kat";
      uid = 1001;
      home = "/home/kat";
      shell = pkgs.zsh;
    };
  };

  system.stateVersion = "18.03";
}