defmodule Mix.Tasks.Hex.SearchTest do
  use HexTest.IntegrationCase

  defmodule SearchDeps.MixProject do
    def project do
      [
        app: :search_app,
        version: "0.0.1",
        deps: [
          {:foo, "0.1.0"}
        ]
      ]
    end
  end

  describe "hexdocs" do
    test "no args" do
      Mix.Project.push(SearchDeps.MixProject)

      in_tmp(fn ->
        write_search_deps()
        Mix.Tasks.Hex.Search.run([])
        assert_received {:hex_system_cmd, _, ["https://hexdocs.pm/?packages=" <> packages]}

        vsn = System.version()

        assert packages =~
                 URI.encode_www_form(
                   "bar:0.1.0,eex:#{vsn},elixir:#{vsn},ex_unit:#{vsn},foo:0.1.0"
                 )

        assert String.ends_with?(packages, "&q=")
      end)
    end

    test "--no-stdlib" do
      Mix.Project.push(SearchDeps.MixProject)

      in_tmp(fn ->
        write_search_deps()
        Mix.Tasks.Hex.Search.run(["--no-stdlib"])
        assert_received {:hex_system_cmd, _, ["https://hexdocs.pm/?packages=" <> packages]}

        assert packages =~ URI.encode_www_form("bar:0.1.0,foo:0.1.0")
        assert String.ends_with?(packages, "&q=")
      end)
    end

    test "--print-url" do
      Mix.Project.push(SearchDeps.MixProject)

      in_tmp(fn ->
        write_search_deps()
        Mix.Tasks.Hex.Search.run(["--print-url"])
        assert_received {:mix_shell, :info, ["https://hexdocs.pm/?packages=" <> packages]}

        vsn = System.version()

        assert packages =~
                 URI.encode_www_form(
                   "bar:0.1.0,eex:#{vsn},elixir:#{vsn},ex_unit:#{vsn},foo:0.1.0"
                 )

        assert String.ends_with?(packages, "&q=")
      end)
    end

    defp write_search_deps do
      set_home_tmp()
      Mix.Dep.Lock.write(%{foo: {:hex, :foo, "0.1.0"}, bar: {:hex, :bar, "0.1.0"}})
      Mix.Task.run("deps.get")
      flush()
    end
  end

  describe "package" do
    test "backwards compatibility" do
      Mix.Tasks.Hex.Search.run(["bloopdoopbloop"])

      assert_received {:mix_shell, :error,
                       ["mix hex.search PACKAGE is deprecated, use --package PACKAGE instead"]}

      assert_received {:mix_shell, :info, ["No packages found"]}
    end

    test "no results" do
      Mix.Tasks.Hex.Search.run(["--package", "bloopdoopbloop"])
      assert_received {:mix_shell, :info, ["No packages found"]}
    end

    test "public packages" do
      Mix.Tasks.Hex.Search.run(["--package", "doc"])
      assert_received {:mix_shell, :info, ["ex_doc" <> ex_doc]}
      assert_received {:mix_shell, :info, ["only_doc" <> only_doc]}
      assert ex_doc =~ ~r"\w*0\.1\.0.*http://localhost:4043/packages/ex_doc"
      assert only_doc =~ ~r"\w*0\.1\.0.*http://localhost:4043/packages/only_doc"
    end

    test "all private packages" do
      in_tmp(fn ->
        set_home_tmp()
        auth = Hexpm.new_user("searchuser1", "searchuser1@mail.com", "password", "searchuser1")
        Hexpm.new_repo("searchrepo1", auth)
        Hex.State.put(:api_key, auth[:key])

        Mix.Tasks.Hex.Search.run(["--package", "doc"])

        assert_received {:mix_shell, :info, ["ex_doc" <> ex_doc]}
        assert_received {:mix_shell, :info, ["only_doc" <> only_doc]}
        assert ex_doc =~ ~r"\w*0\.1\.0.*http://localhost:4043/packages/ex_doc"
        assert only_doc =~ ~r"\w*0\.1\.0.*http://localhost:4043/packages/only_doc"
      end)
    end

    test "org packages" do
      in_tmp(fn ->
        set_home_tmp()
        auth = Hexpm.new_user("searchuser2", "searchuser2@mail.com", "password", "searchuser2")
        Hexpm.new_repo("searchrepo2", auth)
        Hex.State.put(:api_key, auth[:key])

        Mix.Tasks.Hex.Search.run(["--package", "doc", "--organization", "searchrepo2"])

        refute_received {:mix_shell, :info, ["ex_doc" <> _]}
        refute_received {:mix_shell, :info, ["only_doc" <> _]}
      end)
    end
  end
end
