[wip] Refactoring

This PR might look huge but it's mostly:

1. Moving files to new packages.
2. Splitting files into smaller files.
3. Moving away from global variables.
4. Decoupling different parts through interfaces.

I was trying to just put in the Gorilla router but having dependent code in the `main` package made it impossible to separate out the Gorilla router so I just started refactoring.

@xiangli-cmu Feel free to continue working on this. Otherwise I'll finish it up tomorrow. I don't think it's too far off from being done. After that, we can start adding unit tests everywhere to get better coverage. I also think it'd be a good idea to extract the long running test harness into its own standalone repo. Otherwise it's hard to use TDD since tests take 80s to run each time.