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

#include "chrome/browser/ui/user_education/tutorial/tutorial.h"

#include "base/bind.h"
#include "chrome/browser/ui/user_education/tutorial/tutorial_bubble.h"
#include "chrome/browser/ui/user_education/tutorial/tutorial_bubble_factory.h"
#include "chrome/browser/ui/user_education/tutorial/tutorial_bubble_factory_registry.h"
#include "chrome/browser/ui/user_education/tutorial/tutorial_description.h"
#include "chrome/browser/ui/user_education/tutorial/tutorial_service.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/base/interaction/element_identifier.h"
#include "ui/base/interaction/element_tracker.h"
#include "ui/base/interaction/interaction_sequence.h"

Tutorial::StepBuilder::StepBuilder()
    : step_builder_(std::make_unique<ui::InteractionSequence::StepBuilder>()) {}
Tutorial::StepBuilder::~StepBuilder() = default;

// static
std::unique_ptr<ui::InteractionSequence::Step>
Tutorial::StepBuilder::BuildFromDescriptionStep(
    TutorialDescription::Step step,
    absl::optional<std::pair<int, int>> progress,
    bool is_last_step,
    TutorialService* tutorial_service,
    TutorialBubbleFactoryRegistry* bubble_factory_registry) {
  Tutorial::StepBuilder step_builder;

  step_builder.SetAnchorElementID(step.element_id)
      .SetTitleText(step.title_text)
      .SetBodyText(step.body_text)
      .SetStepType(step.step_type)
      .SetProgress(progress)
      .SetArrow(step.arrow)
      .SetIsLastStep(is_last_step);

  return step_builder.Build(tutorial_service, bubble_factory_registry);
}

Tutorial::StepBuilder& Tutorial::StepBuilder::SetAnchorElementID(
    ui::ElementIdentifier element_id_) {
  step_builder_->SetElementID(element_id_);
  return *this;
}

Tutorial::StepBuilder& Tutorial::StepBuilder::SetTitleText(
    absl::optional<std::u16string> title_text_) {
  this->title_text = title_text_;
  return *this;
}

Tutorial::StepBuilder& Tutorial::StepBuilder::SetBodyText(
    absl::optional<std::u16string> body_text_) {
  this->body_text = body_text_;
  return *this;
}

Tutorial::StepBuilder& Tutorial::StepBuilder::SetStepType(
    ui::InteractionSequence::StepType step_type_) {
  step_builder_->SetType(step_type_);
  return *this;
}

Tutorial::StepBuilder& Tutorial::StepBuilder::SetProgress(
    absl::optional<std::pair<int, int>> progress_) {
  this->progress = progress_;
  return *this;
}

Tutorial::StepBuilder& Tutorial::StepBuilder::SetArrow(
    TutorialDescription::Step::Arrow arrow_) {
  this->arrow = arrow_;
  return *this;
}

Tutorial::StepBuilder& Tutorial::StepBuilder::SetIsLastStep(
    bool is_last_step_) {
  this->is_last_step = is_last_step_;
  return *this;
}

std::unique_ptr<ui::InteractionSequence::Step> Tutorial::StepBuilder::Build(
    TutorialService* tutorial_service,
    TutorialBubbleFactoryRegistry* bubble_factory_registry) {
  step_builder_->SetStartCallback(
      BuildShowBubbleCallback(tutorial_service, bubble_factory_registry));
  step_builder_->SetEndCallback(BuildHideBubbleCallback(tutorial_service));

  return step_builder_->Build();
}

ui::InteractionSequence::StepStartCallback
Tutorial::StepBuilder::BuildShowBubbleCallback(
    TutorialService* tutorial_service,
    TutorialBubbleFactoryRegistry* bubble_factory_registry) {
  return base::BindOnce(
      [](TutorialService* tutorial_service,
         TutorialBubbleFactoryRegistry* bubble_factory_registry,
         absl::optional<std::u16string> title_text_,
         absl::optional<std::u16string> body_text_,
         TutorialDescription::Step::Arrow arrow_,
         absl::optional<std::pair<int, int>> progress_, bool is_last_step_,
         ui::InteractionSequence* sequence, ui::TrackedElement* element) {
        DCHECK(tutorial_service);
        DCHECK(bubble_factory_registry);

        tutorial_service->HideCurrentBubbleIfShowing();

        base::RepeatingClosure abort_callback = base::BindRepeating(
            [](TutorialService* tutorial_service) {
              tutorial_service->AbortTutorial();
            },
            base::Unretained(tutorial_service));

        std::unique_ptr<TutorialBubble> bubble =
            bubble_factory_registry->CreateBubbleForTrackedElement(
                element, title_text_, body_text_, arrow_, progress_,
                std::move(abort_callback), is_last_step_);
        tutorial_service->SetCurrentBubble(std::move(bubble));
      },
      base::Unretained(tutorial_service),
      base::Unretained(bubble_factory_registry), title_text, body_text, arrow,
      progress, is_last_step);
}

ui::InteractionSequence::StepEndCallback
Tutorial::StepBuilder::BuildHideBubbleCallback(
    TutorialService* tutorial_service) {
  return base::BindOnce(
      [](TutorialService* tutorial_service, ui::TrackedElement* element) {},
      base::Unretained(tutorial_service));
}

Tutorial::Builder::Builder()
    : builder_(std::make_unique<ui::InteractionSequence::Builder>()) {}
Tutorial::Builder::~Builder() = default;

// static
std::unique_ptr<Tutorial> Tutorial::Builder::BuildFromDescription(
    TutorialDescription description,
    TutorialService* tutorial_service,
    TutorialBubbleFactoryRegistry* bubble_factory_registry,
    ui::ElementContext context) {
  Tutorial::Builder builder;
  builder.SetContext(context);

  int visible_step_count = 0;
  for (const auto& step : description.steps) {
    if (step.ShouldShowBubble())
      visible_step_count++;
  }
  DCHECK(visible_step_count > 0);

  int current_step = 0;
  for (const auto& step : description.steps) {
    builder.AddStep(Tutorial::StepBuilder::BuildFromDescriptionStep(
        step, std::pair<int, int>(current_step, visible_step_count - 1),
        &step == &description.steps.back(), tutorial_service,
        bubble_factory_registry));
    if (step.ShouldShowBubble())
      current_step++;
  }
  DCHECK(visible_step_count == current_step);

  builder.SetAbortedCallback(base::BindOnce(
      [](TutorialService* tutorial_service, ui::TrackedElement* last_element,
         ui::ElementIdentifier last_id,
         ui::InteractionSequence::StepType last_step_type,
         ui::InteractionSequence::AbortedReason aborted_reason) {
        tutorial_service->AbortTutorial();
      },
      tutorial_service));

  builder.SetCompletedCallback(base::BindOnce(
      [](TutorialService* tutorial_service) {
        tutorial_service->CompleteTutorial();
      },
      tutorial_service));

  return builder.Build();
}

Tutorial::Builder& Tutorial::Builder::AddStep(
    std::unique_ptr<ui::InteractionSequence::Step> step) {
  builder_->AddStep(std::move(step));
  return *this;
}

Tutorial::Builder& Tutorial::Builder::SetAbortedCallback(
    ui::InteractionSequence::AbortedCallback callback) {
  builder_->SetAbortedCallback(std::move(callback));
  return *this;
}

Tutorial::Builder& Tutorial::Builder::SetCompletedCallback(
    ui::InteractionSequence::CompletedCallback callback) {
  builder_->SetCompletedCallback(std::move(callback));
  return *this;
}

Tutorial::Builder& Tutorial::Builder::SetContext(
    ui::ElementContext element_context) {
  builder_->SetContext(element_context);
  return *this;
}

std::unique_ptr<Tutorial> Tutorial::Builder::Build() {
  return absl::WrapUnique(new Tutorial(builder_->Build()));
}

Tutorial::Tutorial(
    std::unique_ptr<ui::InteractionSequence> interaction_sequence)
    : interaction_sequence_(std::move(interaction_sequence)) {}
Tutorial::~Tutorial() = default;

void Tutorial::Start() {
  DCHECK(interaction_sequence_);
  if (interaction_sequence_)
    interaction_sequence_->Start();
}

void Tutorial::Abort() {
  if (interaction_sequence_)
    interaction_sequence_.reset();
}
