// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "fuchsia_web/common/test/test_navigation_listener.h"

#include <string>
#include <utility>

#include "base/auto_reset.h"
#include "base/check.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/logging.h"
#include "base/run_loop.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "url/gurl.h"

namespace {

const char* PageTypeToString(fuchsia::web::PageType type) {
  return type == fuchsia::web::PageType::NORMAL ? "NORMAL" : "ERROR";
}

}  // namespace

TestNavigationListener::TestNavigationListener() {
  // Set up the default acknowledgement handling behavior.
  SetBeforeAckHook({});
}

TestNavigationListener::~TestNavigationListener() = default;

void TestNavigationListener::RunUntilNavigationStateMatches(
    const fuchsia::web::NavigationState& expected_state) {
  DCHECK(before_ack_);
  DCHECK(!expected_state_);

  expected_state_ = &expected_state;
  if (!AllFieldsMatch(nullptr)) {
    // Spin the runloop until the expected conditions are met.
    base::RunLoop run_loop;
    base::AutoReset<BeforeAckCallback> callback_setter(
        &before_ack_,
        base::BindRepeating(&TestNavigationListener::QuitLoopIfAllFieldsMatch,
                            base::Unretained(this), run_loop.QuitClosure(),
                            before_ack_));
    run_loop.Run();
  }
  expected_state_ = nullptr;
}

void TestNavigationListener::RunUntilLoaded() {
  fuchsia::web::NavigationState state;
  state.set_page_type(fuchsia::web::PageType::NORMAL);
  state.set_is_main_document_loaded(true);
  RunUntilNavigationStateMatches(state);
}

void TestNavigationListener::RunUntilUrlEquals(const GURL& expected_url) {
  fuchsia::web::NavigationState state;
  state.set_url(expected_url.spec());
  state.set_page_type(fuchsia::web::PageType::NORMAL);
  state.set_is_main_document_loaded(true);
  RunUntilNavigationStateMatches(state);
}

void TestNavigationListener::RunUntilTitleEquals(
    const base::StringPiece expected_title) {
  fuchsia::web::NavigationState state;
  state.set_title(std::string(expected_title));
  state.set_page_type(fuchsia::web::PageType::NORMAL);
  RunUntilNavigationStateMatches(state);
}

void TestNavigationListener::RunUntilUrlAndTitleEquals(
    const GURL& expected_url,
    const base::StringPiece expected_title) {
  fuchsia::web::NavigationState state;
  state.set_url(expected_url.spec());
  state.set_title(std::string(expected_title));
  state.set_page_type(fuchsia::web::PageType::NORMAL);
  RunUntilNavigationStateMatches(state);
}

void TestNavigationListener::RunUntilErrorPageIsLoadedAndTitleEquals(
    base::StringPiece expected_title) {
  fuchsia::web::NavigationState state;
  state.set_title(std::string(expected_title));
  state.set_page_type(fuchsia::web::PageType::ERROR);
  state.set_is_main_document_loaded(true);
  RunUntilNavigationStateMatches(state);
}

void TestNavigationListener::RunUntilUrlTitleBackForwardEquals(
    const GURL& expected_url,
    base::StringPiece expected_title,
    bool expected_can_go_back,
    bool expected_can_go_forward) {
  fuchsia::web::NavigationState state;
  state.set_url(expected_url.spec());
  state.set_title(std::string(expected_title));
  state.set_page_type(fuchsia::web::PageType::NORMAL);
  state.set_can_go_back(expected_can_go_back);
  state.set_can_go_forward(expected_can_go_forward);
  RunUntilNavigationStateMatches(state);
}

void TestNavigationListener::SetBeforeAckHook(BeforeAckCallback send_ack_cb) {
  if (send_ack_cb) {
    before_ack_ = send_ack_cb;
  } else {
    before_ack_ = base::BindRepeating(
        [](const fuchsia::web::NavigationState&,
           OnNavigationStateChangedCallback callback) { callback(); });
  }
}

void TestNavigationListener::OnNavigationStateChanged(
    fuchsia::web::NavigationState changes,
    OnNavigationStateChangedCallback callback) {
  DCHECK(before_ack_);

  // Update our local cache of the Frame's current state.
  if (changes.has_url())
    current_state_.set_url(changes.url());
  if (changes.has_title())
    current_state_.set_title(changes.title());
  if (changes.has_can_go_back())
    current_state_.set_can_go_back(changes.can_go_back());
  if (changes.has_can_go_forward())
    current_state_.set_can_go_forward(changes.can_go_forward());
  if (changes.has_page_type())
    current_state_.set_page_type(changes.page_type());
  if (changes.has_is_main_document_loaded()) {
    current_state_.set_is_main_document_loaded(
        changes.is_main_document_loaded());
  }
  if (changes.has_favicon()) {
    current_state_.set_favicon(std::move(*changes.mutable_favicon()));
  }

  if (VLOG_IS_ON(1)) {
    std::string state_string;
    state_string.reserve(100);

    if (current_state_.has_url()) {
      state_string.append(
          base::StringPrintf(" url=%s ", current_state_.url().c_str()));
    }

    if (current_state_.has_title()) {
      state_string.append(
          base::StringPrintf(" title='%s' ", current_state_.title().c_str()));
    }

    if (current_state_.has_can_go_back()) {
      state_string.append(
          base::StringPrintf(" can_go_back=%d ", current_state_.can_go_back()));
    }

    if (current_state_.has_can_go_forward()) {
      state_string.append(base::StringPrintf(" can_go_forward=%d ",
                                             current_state_.can_go_forward()));
    }

    if (current_state_.has_page_type()) {
      state_string.append(base::StringPrintf(
          " page_type=%s ", PageTypeToString(current_state_.page_type())));
    }

    if (current_state_.has_is_main_document_loaded()) {
      state_string.append(
          base::StringPrintf(" is_main_document_loaded=%d ",
                             current_state_.is_main_document_loaded()));
    }

    VLOG(1) << "Navigation state changed: " << state_string;
  }

  last_changes_ = std::move(changes);

  // Signal readiness for the next navigation event.
  before_ack_.Run(last_changes_, std::move(callback));
}

bool TestNavigationListener::AllFieldsMatch(
    std::vector<FailureReason>* failure_reasons) {
  bool success = true;

  if (expected_state_->has_url() &&
      (!current_state_.has_url() ||
       expected_state_->url() != current_state_.url())) {
    if (failure_reasons) {
      failure_reasons->push_back({"url", expected_state_->url()});
    }
    success = false;
  }

  if (expected_state_->has_title() &&
      (!current_state_.has_title() ||
       expected_state_->title() != current_state_.title())) {
    if (failure_reasons) {
      failure_reasons->push_back({"title", expected_state_->title()});
    }
    success = false;
  }

  if (expected_state_->has_can_go_forward() &&
      (!current_state_.has_can_go_forward() ||
       expected_state_->can_go_forward() != current_state_.can_go_forward())) {
    if (failure_reasons) {
      failure_reasons->push_back(
          {"can_go_forward",
           base::NumberToString(expected_state_->can_go_forward())});
    }
    success = false;
  }

  if (expected_state_->has_can_go_back() &&
      (!current_state_.has_can_go_back() ||
       expected_state_->can_go_back() != current_state_.can_go_back())) {
    if (failure_reasons) {
      failure_reasons->push_back(
          {"can_go_back",
           base::NumberToString(expected_state_->can_go_back())});
    }
    success = false;
  }

  if (expected_state_->has_page_type() &&
      (!current_state_.has_page_type() ||
       expected_state_->page_type() != current_state_.page_type())) {
    if (failure_reasons) {
      failure_reasons->push_back(
          {"page_type", PageTypeToString(expected_state_->page_type())});
    }
    success = false;
  }

  if (expected_state_->has_is_main_document_loaded() &&
      (!current_state_.has_is_main_document_loaded() ||
       expected_state_->is_main_document_loaded() !=
           current_state_.is_main_document_loaded())) {
    if (failure_reasons) {
      failure_reasons->push_back(
          {"is_main_document_loaded",
           base::NumberToString(expected_state_->is_main_document_loaded())});
    }
    success = false;
  }

  return success;
}

void TestNavigationListener::QuitLoopIfAllFieldsMatch(
    base::RepeatingClosure quit_run_loop_closure,
    TestNavigationListener::BeforeAckCallback before_ack_callback,
    const fuchsia::web::NavigationState& change,
    fuchsia::web::NavigationEventListener::OnNavigationStateChangedCallback
        ack_callback) {
  std::vector<FailureReason> failure_reasons;

  if (AllFieldsMatch(VLOG_IS_ON(1) ? &failure_reasons : nullptr)) {
    VLOG(1) << "All navigation expectations satisfied, continuing...";
    quit_run_loop_closure.Run();
  } else if (VLOG_IS_ON(1)) {
    std::vector<std::string> formatted_reasons;
    for (const auto& reason : failure_reasons) {
      formatted_reasons.push_back(base::StringPrintf("%s=%s", reason.field_name,
                                                     reason.expected.c_str()));
    }
    VLOG(1) << "Still waiting on the following unmet expectations: "
            << base::JoinString(formatted_reasons, ", ");
  }

  before_ack_callback.Run(change, std::move(ack_callback));
}
