Feature - Handling Environments

This PR was created for the purpose of handling different environments and building them into classes that can be strictly type checked.

The EnvironmentFactory class can either take in a string, use the current `ENVIRONMENT` variable, or default to a `development` environment.

If the environment isn't recognized as one of the defined (development, staging, production) we create a CustomEnvironment class which will allow for custom configurations in the future.
Why not just `@return AbstractEnvironment`? Keeping this list up to date with every new environment would be cumbersome, and its not the doc style that we currently use (we usually refer to the interface or abstract class that may be returned). It would make sense to list multiple classes if they didn't have a common parent or interface.