// Copyright 2019 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.

#import "ios/web/find_in_page/find_in_page_manager_impl.h"

#include "base/metrics/user_metrics.h"
#include "base/metrics/user_metrics_action.h"
#import "base/strings/sys_string_conversions.h"
#include "base/task/post_task.h"
#include "base/values.h"
#import "ios/web/find_in_page/find_in_page_constants.h"
#import "ios/web/find_in_page/find_in_page_java_script_feature.h"
#import "ios/web/public/find_in_page/find_in_page_manager_delegate.h"
#import "ios/web/public/js_messaging/web_frame.h"
#include "ios/web/public/js_messaging/web_frame_util.h"
#import "ios/web/public/js_messaging/web_frames_manager.h"
#include "ios/web/public/thread/web_task_traits.h"
#import "ios/web/web_state/web_state_impl.h"

#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif

namespace web {

// static
FindInPageManagerImpl::FindInPageManagerImpl(WebState* web_state)
    : web_state_(web_state), weak_factory_(this) {
  web_state_->AddObserver(this);
}

void FindInPageManagerImpl::CreateForWebState(WebState* web_state) {
  DCHECK(web_state);
  if (!FromWebState(web_state)) {
    web_state->SetUserData(UserDataKey(),
                           std::make_unique<FindInPageManagerImpl>(web_state));
  }
}

FindInPageManagerImpl::~FindInPageManagerImpl() {
  if (web_state_) {
    web_state_->RemoveObserver(this);
    web_state_ = nullptr;
  }
}

FindInPageManagerDelegate* FindInPageManagerImpl::GetDelegate() {
  return delegate_;
}
void FindInPageManagerImpl::SetDelegate(FindInPageManagerDelegate* delegate) {
  delegate_ = delegate;
}

void FindInPageManagerImpl::WebFrameDidBecomeAvailable(WebState* web_state,
                                                       WebFrame* web_frame) {
  const std::string frame_id = web_frame->GetFrameId();
  last_find_request_.AddFrame(web_frame);
}

void FindInPageManagerImpl::WebFrameWillBecomeUnavailable(WebState* web_state,
                                                          WebFrame* web_frame) {
  int match_count =
      last_find_request_.GetMatchCountForFrame(web_frame->GetFrameId());
  last_find_request_.RemoveFrame(web_frame->GetFrameId());

  // Only notify the delegate if the match count has changed.
  if (delegate_ && last_find_request_.GetRequestQuery() && match_count > 0) {
    delegate_->DidHighlightMatches(web_state_,
                                   last_find_request_.GetTotalMatchCount(),
                                   last_find_request_.GetRequestQuery());
  }
}

void FindInPageManagerImpl::WebStateDestroyed(WebState* web_state) {
  web_state_->RemoveObserver(this);
  web_state_ = nullptr;
}

void FindInPageManagerImpl::Find(NSString* query, FindInPageOptions options) {
  DCHECK(CanSearchContent());

  switch (options) {
    case FindInPageOptions::FindInPageSearch:
      DCHECK(query);
      StartSearch(query);
      break;
    case FindInPageOptions::FindInPageNext:
      SelectNextMatch();
      break;
    case FindInPageOptions::FindInPagePrevious:
      SelectPreviousMatch();
      break;
  }
}

void FindInPageManagerImpl::StartSearch(NSString* query) {
  base::RecordAction(base::UserMetricsAction(kFindActionName));
  std::set<WebFrame*> all_frames =
      web_state_->GetWebFramesManager()->GetAllWebFrames();
  last_find_request_.Reset(query, all_frames.size());
  if (all_frames.size() == 0) {
    // No frames to search in.
    // Call asyncronously to match behavior if find was successful in frames.
    base::PostTask(
        FROM_HERE, {WebThread::UI},
        base::BindOnce(&FindInPageManagerImpl::LastFindRequestCompleted,
                       weak_factory_.GetWeakPtr()));
    return;
  }

  for (WebFrame* frame : all_frames) {
    bool result = FindInPageJavaScriptFeature::GetInstance()->Search(
        frame, base::SysNSStringToUTF8(query),
        base::BindOnce(&FindInPageManagerImpl::ProcessFindInPageResult,
                       weak_factory_.GetWeakPtr(), frame->GetFrameId(),
                       last_find_request_.GetRequestId()));

    if (!result) {
      // Calling JavaScript function failed or the frame does not support
      // messaging.
      last_find_request_.DidReceiveFindResponseFromOneFrame();
      if (last_find_request_.AreAllFindResponsesReturned()) {
        // Call asyncronously to match behavior if find was done in frames.
        base::PostTask(
            FROM_HERE, {WebThread::UI},
            base::BindOnce(&FindInPageManagerImpl::LastFindRequestCompleted,
                           weak_factory_.GetWeakPtr()));
      }
    }
  }
}

void FindInPageManagerImpl::StopFinding() {
  last_find_request_.Reset(/*new_query=*/nil,
                           /*new_pending_frame_call_count=*/0);

  for (WebFrame* frame : web_state_->GetWebFramesManager()->GetAllWebFrames()) {
    FindInPageJavaScriptFeature::GetInstance()->Stop(frame);
  }
  if (delegate_) {
    delegate_->DidHighlightMatches(web_state_,
                                   last_find_request_.GetTotalMatchCount(),
                                   last_find_request_.GetRequestQuery());
  }
}

bool FindInPageManagerImpl::CanSearchContent() {
  return web_state_->ContentIsHTML();
}

void FindInPageManagerImpl::ProcessFindInPageResult(
    const std::string& frame_id,
    const int unique_id,
    base::Optional<int> result_matches) {
  if (unique_id != last_find_request_.GetRequestId()) {
    // New find was started or current find was stopped.
    return;
  }
  if (!web_state_) {
    // WebState was destroyed before find finished.
    return;
  }

  WebFrame* frame = GetWebFrameWithId(web_state_, frame_id);
  if (!result_matches || !frame) {
    // The frame no longer exists or the function call timed out. In both cases,
    // result will be null.
    // Zero out count to ensure every frame is updated for every find.
    last_find_request_.SetMatchCountForFrame(0, frame_id);
  } else {
    // If response is equal to kFindInPagePending, find did not finish in the
    // JavaScript. Call pumpSearch to continue find.
    if (result_matches.value() == find_in_page::kFindInPagePending) {
      FindInPageJavaScriptFeature::GetInstance()->Pump(
          frame,
          base::BindOnce(&FindInPageManagerImpl::ProcessFindInPageResult,
                         weak_factory_.GetWeakPtr(), frame_id, unique_id));
      return;
    }

    last_find_request_.SetMatchCountForFrame(result_matches.value(), frame_id);
  }
  last_find_request_.DidReceiveFindResponseFromOneFrame();
  if (last_find_request_.AreAllFindResponsesReturned()) {
    LastFindRequestCompleted();
  }
}

void FindInPageManagerImpl::LastFindRequestCompleted() {
  if (delegate_) {
    delegate_->DidHighlightMatches(web_state_,
                                   last_find_request_.GetTotalMatchCount(),
                                   last_find_request_.GetRequestQuery());
  }
  int total_matches = last_find_request_.GetTotalMatchCount();
  if (total_matches == 0) {
    return;
  }

  if (last_find_request_.GoToFirstMatch()) {
    SelectCurrentMatch();
  }
}

void FindInPageManagerImpl::SelectDidFinish(const base::Value* result) {
  std::string match_context_string;
  if (result && result->is_dict()) {
    // Get updated match count.
    const base::Value* matches = result->FindKey(kSelectAndScrollResultMatches);
    if (matches && matches->is_double()) {
      int match_count = static_cast<int>(matches->GetDouble());
      if (match_count != last_find_request_.GetMatchCountForSelectedFrame()) {
        last_find_request_.SetMatchCountForSelectedFrame(match_count);
        if (delegate_) {
          delegate_->DidHighlightMatches(
              web_state_, last_find_request_.GetTotalMatchCount(),
              last_find_request_.GetRequestQuery());
        }
      }
    }
    // Get updated currently selected index.
    const base::Value* index = result->FindKey(kSelectAndScrollResultIndex);
    if (index && index->is_double()) {
      int current_index = static_cast<int>(index->GetDouble());
      last_find_request_.SetCurrentSelectedMatchFrameIndex(current_index);
    }
    // Get context string.
    const base::Value* context_string =
        result->FindKey(kSelectAndScrollResultContextString);
    if (context_string && context_string->is_string()) {
      match_context_string =
          static_cast<std::string>(context_string->GetString());
    }
  }
  if (delegate_) {
    delegate_->DidSelectMatch(
        web_state_, last_find_request_.GetCurrentSelectedMatchPageIndex(),
        base::SysUTF8ToNSString(match_context_string));
  }
}

void FindInPageManagerImpl::SelectNextMatch() {
  base::RecordAction(base::UserMetricsAction(kFindNextActionName));
  if (last_find_request_.GoToNextMatch()) {
    SelectCurrentMatch();
  }
}

void FindInPageManagerImpl::SelectPreviousMatch() {
  base::RecordAction(base::UserMetricsAction(kFindPreviousActionName));
  if (last_find_request_.GoToPreviousMatch()) {
    SelectCurrentMatch();
  }
}

void FindInPageManagerImpl::SelectCurrentMatch() {
  web::WebFrame* frame =
      GetWebFrameWithId(web_state_, last_find_request_.GetSelectedFrameId());
  if (frame) {
    FindInPageJavaScriptFeature::GetInstance()->SelectMatch(
        frame, last_find_request_.GetCurrentSelectedMatchFrameIndex(),
        base::BindOnce(&FindInPageManagerImpl::SelectDidFinish,
                       weak_factory_.GetWeakPtr()));
  }
}

WEB_STATE_USER_DATA_KEY_IMPL(FindInPageManager)

}  // namespace web
