     end
   end
 
+  @doc """
+  Returns the platform for the host system.
+
+  ## Example return values
+    "win"
+    "linux"
+    "darwin"
+  """
+  @spec host_platform() :: String.t
   def host_platform() do
     :erlang.system_info(:system_architecture)
     |> to_string
     |> parse_platform
   end
-
+  @doc false
   def parse_platform(platform) when is_binary(platform) do
     platform
     |> String.split("-")
     |> parse_platform
   end
+  @doc false
   def parse_platform(platform) when is_list(platform) do
     case platform do
       [<<"win", _tail :: binary>> | _] ->

defmodule Nerves.Env do
  alias Nerves.Package

  # Pre 0.4.0 Legacy
  def initialize, do: start()
  def stale? do
    system_manifest =
      system_path()
      |> Path.join(".nerves.lock")
      |> Path.expand

    if stale_check_manifest(system_manifest) do
      false
    else
      true
    end
  end

  def stale_check_manifest(manifest) do
    case File.read(manifest) do
      {:ok, file} ->
        file
        |> :erlang.binary_to_term
        |> Keyword.equal?(packages())
      _ -> false
    end
  end
  def deps, do: packages()
  def deps_by_type(type), do: packages_by_type(type)
  ## End Pre 0.4.0 Legacy

  def start do
    Agent.start_link fn -> load_packages() end, name: __MODULE__
  end

  def stop do
    Agent.stop(__MODULE__)
  end

  def ensure_loaded(app, path \\ nil) do
    path = path || File.cwd!

    Agent.update(__MODULE__, fn(packages) ->
      case Enum.find(packages, & &1.app == app) do
        nil ->
          package = Package.load_config({app, path})
          [package | packages]
        _ -> packages
      end
    end)
  end

  def host_arch() do
    :erlang.system_info(:system_architecture)
    |> to_string
    |> parse_arch
  end

  def parse_arch(arch) when is_binary(arch) do
    arch
    |> String.split("-")
    |> parse_arch
  end
  def parse_arch(arch) when is_list(arch) do
    arch = List.first(arch)
    case arch do

    platform.bootstrap(pkg)
  end

  @doc false
  defp load_packages do
    Mix.Project.deps_paths
    |> Enum.filter(fn({_, path}) ->
      Package.config_path(path)
      |> File.exists?
    end)
    |> Enum.map(&Package.load_config/1)
    |> validate_packages
  end

  @doc false
  defp validate_packages(packages) do
    for type <- [:system, :toolchain] do
      packages_by_type(type, packages)
      |> validate_one(type)
    end
    packages
  end

  @doc false
  defp validate_one(packages, type) when length(packages) > 1 do
    packages = Enum.map(packages, &(Map.get(&1, :app)))
    Mix.raise """
    Your mix project cannot contain more than one #{type} for the target.
    Your dependancies for the target contian the following #{type}s:
    #{Enum.join(packages, ~s/ /)}
    """
  end
  @doc false
  defp validate_one(packages, _type), do: packages

  @doc false
  defp toolchain_path do
    toolchain = Nerves.Env.toolchain
    Nerves.Package.Artifact.dir(toolchain, toolchain)
  end
  @doc false
  defp system_path do
    system = Nerves.Env.system
    toolchain = Nerves.Env.toolchain
    Nerves.Package.Artifact.dir(system, toolchain)
  end

  # Pre 0.4.0 Legacy
  @doc false
  def initialize, do: start()
  @doc false
  def stale? do
    system_manifest =
      system_path()
      |> Path.join(".nerves.lock")
      |> Path.expand

    if stale_check_manifest(system_manifest) do
      false
    else
      true
    end
  end
  @doc false
  def stale_check_manifest(manifest) do
    case File.read(manifest) do
      {:ok, file} ->
        file
        |> :erlang.binary_to_term
        |> Keyword.equal?(packages())
      _ -> false
    end
  end
  @doc false
  def deps, do: packages()
  @doc false
  def deps_by_type(type), do: packages_by_type(type)
  ## End Pre 0.4.0 Legacy

end
