defmodule Couch.DBTest do
  @moduledoc false

  import ExUnit.Callbacks, only: [on_exit: 1]
  import ExUnit.Assertions, only: [assert: 1, assert: 2]

  def set_db_context(context) do
    context =
      case context do
        %{:with_db_name => true} ->
          Map.put(context, :db_name, random_db_name())

        %{:with_db_name => db_name} when is_binary(db_name) ->
          Map.put(context, :db_name, db_name)

        %{:with_random_db => db_name} when is_binary(db_name) ->
          context
          |> Map.put(:db_name, random_db_name(db_name))
          |> Map.put(:with_db, true)

        %{:with_partitioned_db => true} ->
          context
          |> Map.put(:db_name, random_db_name())
          |> Map.put(:query, %{partitioned: true})
          |> Map.put(:with_db, true)

        %{:with_db => true} ->
          Map.put(context, :db_name, random_db_name())

        %{:with_db => db_name} when is_binary(db_name) ->
          Map.put(context, :db_name, db_name)

        _ ->
          context
      end

    if Map.has_key?(context, :with_db) do
      {:ok, _} = create_db(context[:db_name], query: context[:query])
      on_exit(fn -> delete_db(context[:db_name]) end)
    end

    context
  end

  def set_config_context(context) do
    if is_list(context[:config]) do
      Enum.each(context[:config], fn cfg ->
        set_config(cfg)
      end)
    end

    context
  end

  def set_user_context(context) do
    case Map.get(context, :user) do
      nil ->
        context

      user when is_list(user) ->
        user = create_user(user)

        on_exit(fn ->
          query = %{:rev => user["_rev"]}
          resp = Couch.delete("/_users/#{user["_id"]}", query: query)
          assert HTTPotion.Response.success?(resp)
        end)

        context = Map.put(context, :user, user)
        userinfo = user["name"] <> ":" <> user["password"]
        Map.put(context, :userinfo, userinfo)
    end
  end

  def random_db_name do
    random_db_name("random-test-db")
  end

  def random_db_name(prefix) do
    time = :erlang.monotonic_time()
    umi = :erlang.unique_integer([:monotonic])
    "#{prefix}-#{time}-#{umi}"
  end

  def set_config({section, key, value}) do
    existing = set_config_raw(section, key, value)

    on_exit(fn ->
      Enum.each(existing, fn {node, prev_value} ->
        if prev_value != "" do
          url = "/_node/#{node}/_config/#{section}/#{key}"
          headers = ["X-Couch-Persist": "false"]
          body = :jiffy.encode(prev_value)
          resp = Couch.put(url, headers: headers, body: body)
          assert resp.status_code == 200
        else
          url = "/_node/#{node}/_config/#{section}/#{key}"
          headers = ["X-Couch-Persist": "false"]
          resp = Couch.delete(url, headers: headers)
          assert resp.status_code == 200
        end
      end)
    end)
  end

  def set_config_raw(section, key, value) do
    resp = Couch.get("/_membership")

    Enum.map(resp.body["all_nodes"], fn node ->
      url = "/_node/#{node}/_config/#{section}/#{key}"
      headers = ["X-Couch-Persist": "false"]
      body = :jiffy.encode(value)
      resp = Couch.put(url, headers: headers, body: body)
      assert resp.status_code == 200
      {node, resp.body}
    end)
  end

  def prepare_user_doc(user) do
    required = [:name, :password]

    Enum.each(required, fn key ->
      assert Keyword.has_key?(user, key), "User missing key: #{key}"
    end)

    id = Keyword.get(user, :id)
    name = Keyword.get(user, :name)
    password = Keyword.get(user, :password)
    roles = Keyword.get(user, :roles, [])

    assert is_binary(name), "User name must be a string"
    assert is_binary(password), "User password must be a string"
    assert is_list(roles), "Roles must be a list of strings"

    Enum.each(roles, fn role ->
      assert is_binary(role), "Roles must be a list of strings"
    end)

    %{
      "_id" => id || "org.couchdb.user:" <> name,
      "type" => "user",
      "name" => name,
      "roles" => roles,
      "password" => password
    }
  end

  def create_user(user) do
    user_doc = prepare_user_doc(user)
    resp = Couch.get("/_users/#{user_doc["_id"]}")

    user_doc =
      case resp.status_code do
        404 ->
          user_doc

        sc when sc >= 200 and sc < 300 ->
          Map.put(user_doc, "_rev", resp.body["_rev"])
      end

    resp = Couch.post("/_users", body: user_doc)
    assert HTTPotion.Response.success?(resp)
    assert resp.body["ok"]
    Map.put(user_doc, "_rev", resp.body["rev"])
  end

  def create_db(db_name, opts \\ []) do
    retry_until(fn ->
      resp = Couch.put("/#{db_name}", opts)
      assert resp.status_code in [201, 202]
      assert resp.body == %{"ok" => true}
      {:ok, resp}
    end)
  end

  def delete_db(db_name) do
    resp = Couch.delete("/#{db_name}")
    assert resp.status_code in [200, 202, 404]
    {:ok, resp}
  end

  def reset_db(db_name, opts \\ []) do
    delete_db(db_name)
    create_db(db_name, opts)
  end

  # Use this function when testing authentication after resetting (re-creating)
  # _users db. The auth cache can take up to 5 seconds or so to notice the old
  # db is gone and spawn another changes feed for the new users db.
  #
  def wait_for_design_auth(users_db) do
    retry_until(fn ->
      resp =
        Couch.get(
          "/#{users_db}/_changes",
          query: [feed: "longpoll", timeout: 5000, filter: "_design"]
        )
      results = resp.body["results"]
      is_list(results) && length(results) > 0
    end, 500, 60_000)
  end

  def create_doc(db_name, body) do
    resp = Couch.post("/#{db_name}", body: body)
    assert resp.status_code in [201, 202]
    assert resp.body["ok"]
    {:ok, resp}
  end

  def info(db_name) do
    resp = Couch.get("/#{db_name}")
    assert resp.status_code == 200
    resp.body
  end

  def save(db_name, document) do
    resp = Couch.put("/#{db_name}/#{document["_id"]}", body: document)
    assert resp.status_code in [201, 202]
    assert resp.body["ok"]
    Map.put(document, "_rev", resp.body["rev"])
  end

  def bulk_save(db_name, docs) do
    resp =
      Couch.post(
        "/#{db_name}/_bulk_docs",
        body: %{
          docs: docs
        }
      )

    assert resp.status_code in [201, 202]
    resp
  end

  def query(
        db_name,
        map_fun,
        reduce_fun \\ nil,
        options \\ nil,
        keys \\ nil,
        language \\ "javascript"
      ) do
    l_map_function =
      if language == "javascript" do
        "#{map_fun} /* avoid race cond #{now(:ms)} */"
      else
        map_fun
      end

    view = %{
      :map => l_map_function
    }

    view =
      if reduce_fun != nil do
        Map.put(view, :reduce, reduce_fun)
      else
        view
      end

    {view, request_options} =
      if options != nil and Map.has_key?(options, :options) do
        {Map.put(view, :options, options.options), Map.delete(options, :options)}
      else
        {view, options}
      end

    ddoc_name = "_design/temp_#{now(:ms)}"

    ddoc = %{
      _id: ddoc_name,
      language: language,
      views: %{
        view: view
      }
    }

    request_options =
      if keys != nil and is_list(keys) do
        Map.merge(request_options || %{}, %{:keys => :jiffy.encode(keys)})
      else
        request_options
      end

    resp =
      Couch.put(
        "/#{db_name}/#{ddoc_name}",
        headers: ["Content-Type": "application/json"],
        body: ddoc
      )

    assert resp.status_code in [201, 202]

    resp = Couch.get("/#{db_name}/#{ddoc_name}/_view/view", query: request_options)
    assert resp.status_code == 200

    Couch.delete("/#{db_name}/#{ddoc_name}")

    resp.body
  end

  def compact(db_name) do
    resp = Couch.post("/#{db_name}/_compact")
    assert resp.status_code == 202

    retry_until(
      fn -> Map.get(info(db_name), "compact_running") == false end,
      200,
      10_000
    )

    resp.body
  end

  def replicate(src, tgt, options \\ []) do
    username = System.get_env("EX_USERNAME") || "adm"
    password = System.get_env("EX_PASSWORD") || "pass"

    {userinfo, options} = Keyword.pop(options, :userinfo)

    userinfo =
      if userinfo == nil do
        "#{username}:#{password}"
      else
        userinfo
      end

    src = set_user(get_absolute_url(src), userinfo)
    tgt = set_user(get_absolute_url(tgt), userinfo)

    defaults = [headers: [], body: %{}, timeout: 30_000]
    options = defaults |> Keyword.merge(options) |> Enum.into(%{})

    %{body: body} = options
    body = [source: src, target: tgt] |> Enum.into(body)
    options = Map.put(options, :body, body)

    resp = Couch.post("/_replicate", Enum.to_list(options))
    assert HTTPotion.Response.success?(resp), "#{inspect(resp)}"
    resp.body
  end

  defp get_absolute_url("http://" <> _ = uri) do
    uri
  end

  defp get_absolute_url("/" <> _ = uri) do
    Couch.process_url(uri)
  end

  defp get_absolute_url(uri) do
    Couch.process_url("/" <> uri)
  end

  defp set_user(uri, userinfo) do
    case URI.parse(uri) do
      %{scheme: nil} ->
        uri

      %{userinfo: nil} = uri ->
        URI.to_string(Map.put(uri, :userinfo, userinfo))

      _ ->
        uri
    end
  end

  def view(db_name, view_name, options \\ nil, keys \\ nil) do
    [view_root, view_name] = String.split(view_name, "/")

    resp =
      case keys do
        nil ->
          Couch.get("/#{db_name}/_design/#{view_root}/_view/#{view_name}", query: options)

        _ ->
          Couch.post("/#{db_name}/_design/#{view_root}/_view/#{view_name}", query: options,
            body: %{"keys" => keys}
          )
      end

    assert resp.status_code in [200, 201]
    resp
  end

  def sample_doc_foo do
    %{
      _id: "foo",
      bar: "baz"
    }
  end

  # Generate range of docs with strings as keys
  def make_docs(id_range) do
    for id <- id_range, str_id = Integer.to_string(id) do
      %{"_id" => str_id, "integer" => id, "string" => str_id}
    end
  end

  # Generate range of docs based on a template
  def make_docs(id_range, template_doc) do
    for id <- id_range, str_id = Integer.to_string(id) do
      Map.merge(template_doc, %{"_id" => str_id})
    end
  end

  # Generate range of docs with atoms as keys, which are more
  # idiomatic, and are encoded by jiffy to binaries
  def create_docs(id_range) do
    for id <- id_range, str_id = Integer.to_string(id) do
      %{_id: str_id, integer: id, string: str_id}
    end
  end

  def request_stats(path_steps, is_test) do
    path =
      List.foldl(
        path_steps,
        "/_node/_local/_stats",
        fn p, acc ->
          "#{acc}/#{p}"
        end
      )

    path =
      if is_test do
        path <> "?flush=true"
      else
        path
      end

    Couch.get(path).body
  end

  def retry_until(condition, sleep \\ 100, timeout \\ 30_000) do
    retry_until(condition, now(:ms), sleep, timeout)
  end

  defp retry_until(condition, start, sleep, timeout, err \\ nil) do
    now = now(:ms)

    if now > start + timeout do
      raise err
    else
      try do
        if result = condition.() do
          result
        else
          raise ExUnit.AssertionError
        end
      rescue
        e in ExUnit.AssertionError ->
          :timer.sleep(sleep)
          retry_until(condition, start, sleep, timeout, e)
      end
    end
  end

  defp now(:ms) do
    case elem(:os.type, 0) do
      :win32 ->
        div(:erlang.system_time(), 1_000)
      _ ->
        div(:erlang.system_time(), 1_000_000)
    end
  end

  @spec rev(map(), map()) :: map()
  def rev(doc = %{_id: id}, %{"id" => id, "rev" => rev}) do
    Map.put(doc, :_rev, rev)
  end

  @spec rev([map()], [map()]) :: [map()]
  def rev(docs, rows) when length(docs) == length(rows) do
    for {doc, row} <- Enum.zip(docs, rows), do: rev(doc, row)
  end

  def pretty_inspect(resp) do
    opts = [pretty: true, width: 20, limit: :infinity, printable_limit: :infinity]
    inspect(resp, opts)
  end

  def run_on_modified_server(settings, fun) do
    resp = Couch.get("/_membership")
    assert resp.status_code == 200
    nodes = resp.body["all_nodes"]

    prev_settings =
      Enum.map(settings, fn setting ->
        prev_setting_node =
          Enum.reduce(nodes, %{}, fn node, acc ->
            resp =
              Couch.put(
                "/_node/#{node}/_config/#{setting.section}/#{setting.key}",
                headers: ["X-Couch-Persist": false],
                body: :jiffy.encode(setting.value)
              )

            assert resp.status_code == 200
            Map.put(acc, node, resp.body)
          end)

        Map.put(setting, :nodes, Map.to_list(prev_setting_node))
      end)

    try do
      fun.()
    after
      Enum.each(prev_settings, fn setting ->
        Enum.each(setting.nodes, fn node_value ->
          node = elem(node_value, 0)
          value = elem(node_value, 1)

          if value == ~s(""\\n) or value == "" or value == nil do
            resp =
              Couch.delete(
                "/_node/#{node}/_config/#{setting.section}/#{setting.key}",
                headers: ["X-Couch-Persist": false]
              )

            assert resp.status_code == 200
          else
            resp =
              Couch.put(
                "/_node/#{node}/_config/#{setting.section}/#{setting.key}",
                headers: ["X-Couch-Persist": false],
                body: :jiffy.encode(value)
              )

            assert resp.status_code == 200
          end
        end)
      end)
    end
  end

  def restart_cluster do
    resp = Couch.get("/_membership")
    assert resp.status_code == 200
    nodes = resp.body["all_nodes"]

    nodes_ports =
      Enum.reduce(nodes, [], fn node, acc ->
        port = node_to_port(node)
        [{node, port} | acc]
      end)

    tasks =
      Enum.map(nodes_ports, fn {node, port} ->
        Task.async(fn -> restart_node(node, port) end)
      end)

    Task.yield_many(tasks, length(nodes) * 5000)
  end

  def restart_node(node \\ "node1@127.0.0.1") do
    port = node_to_port(node)
    restart_node(node, port)
  end

  defp restart_node(node, port) do
    url = "http://127.0.0.1:#{port}/_node/#{node}/_restart"
    resp = Couch.post(url)
    assert HTTPotion.Response.success?(resp)
    assert resp.body["ok"]
    # make sure node went down. we assuming the node can't bounce quick
    # enough to inroduce a race here
    retry_until(fn -> !node_is_running(port) end)
    # wait utill node is back
    retry_until(fn -> node_is_running(port) end, 500, 30_000)
  end

  defp node_is_running(port) do
    url = "http://127.0.0.1:#{port}/_up"
    resp = Couch.get(url)

    case HTTPotion.Response.success?(resp) do
      true -> resp.status_code in 200..399
      false -> false
    end
  end

  defp node_to_port(node) do
    url = "/_node/#{node}/_config/chttpd/port"
    resp = Couch.get(url)
    assert HTTPotion.Response.success?(resp)
    resp.body
  end
end
