// Copyright (c) 2012 The Chromium Embedded Framework 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 "tests/cefclient/browser/dialog_test.h"

#include <string>

#include "include/cef_browser.h"
#include "include/wrapper/cef_helpers.h"
#include "tests/cefclient/browser/test_runner.h"
#include "tests/shared/browser/file_util.h"

namespace client {
namespace dialog_test {

namespace {

const char kTestUrlPath[] = "/dialogs";
const char kFileOpenMessageName[] = "DialogTest.FileOpen";
const char kFileOpenMultipleMessageName[] = "DialogTest.FileOpenMultiple";
const char kFileOpenFolderMessageName[] = "DialogTest.FileOpenFolder";
const char kFileSaveMessageName[] = "DialogTest.FileSave";

// Store persistent dialog state information.
class DialogState : public base::RefCountedThreadSafe<DialogState> {
 public:
  DialogState()
      : mode_(FILE_DIALOG_OPEN), last_selected_filter_(0), pending_(false) {}

  cef_file_dialog_mode_t mode_;
  int last_selected_filter_;
  CefString last_file_;
  bool pending_;

  DISALLOW_COPY_AND_ASSIGN(DialogState);
};

// Callback executed when the file dialog is dismissed.
class DialogCallback : public CefRunFileDialogCallback {
 public:
  DialogCallback(
      CefRefPtr<CefMessageRouterBrowserSide::Callback> router_callback,
      scoped_refptr<DialogState> dialog_state)
      : router_callback_(router_callback), dialog_state_(dialog_state) {}

  virtual void OnFileDialogDismissed(
      int last_selected_filter,
      const std::vector<CefString>& file_paths) OVERRIDE {
    CEF_REQUIRE_UI_THREAD();
    DCHECK(dialog_state_->pending_);

    if (!file_paths.empty()) {
      if (dialog_state_->mode_ != FILE_DIALOG_OPEN_FOLDER)
        dialog_state_->last_selected_filter_ = last_selected_filter;

      dialog_state_->last_file_ = file_paths[0];
      if (dialog_state_->mode_ == FILE_DIALOG_OPEN_FOLDER) {
        std::string last_file = dialog_state_->last_file_;
        if (last_file[last_file.length() - 1] != file_util::kPathSep) {
          // Add a trailing slash so we know it's a directory. Otherwise, file
          // dialogs will think the last path component is a file name.
          last_file += file_util::kPathSep;
          dialog_state_->last_file_ = last_file;
        }
      }
    }

    // Send a message back to the render process with the list of file paths.
    std::string response;
    for (int i = 0; i < static_cast<int>(file_paths.size()); ++i) {
      if (!response.empty())
        response += "|";  // Use a delimiter disallowed in file paths.
      response += file_paths[i];
    }

    router_callback_->Success(response);
    router_callback_ = nullptr;

    dialog_state_->pending_ = false;
    dialog_state_ = nullptr;
  }

 private:
  CefRefPtr<CefMessageRouterBrowserSide::Callback> router_callback_;
  scoped_refptr<DialogState> dialog_state_;

  IMPLEMENT_REFCOUNTING(DialogCallback);
  DISALLOW_COPY_AND_ASSIGN(DialogCallback);
};

// Handle messages in the browser process.
class Handler : public CefMessageRouterBrowserSide::Handler {
 public:
  Handler() {}

  // Called due to cefQuery execution in dialogs.html.
  virtual bool OnQuery(CefRefPtr<CefBrowser> browser,
                       CefRefPtr<CefFrame> frame,
                       int64 query_id,
                       const CefString& request,
                       bool persistent,
                       CefRefPtr<Callback> callback) OVERRIDE {
    CEF_REQUIRE_UI_THREAD();

    // Only handle messages from the test URL.
    const std::string& url = frame->GetURL();
    if (!test_runner::IsTestURL(url, kTestUrlPath))
      return false;

    if (!dialog_state_.get())
      dialog_state_ = new DialogState;

    // Make sure we're only running one dialog at a time.
    DCHECK(!dialog_state_->pending_);

    std::vector<CefString> accept_filters;
    std::string title;

    const std::string& message_name = request;
    if (message_name == kFileOpenMessageName) {
      dialog_state_->mode_ = FILE_DIALOG_OPEN;
      title = "My Open Dialog";
    } else if (message_name == kFileOpenMultipleMessageName) {
      dialog_state_->mode_ = FILE_DIALOG_OPEN_MULTIPLE;
      title = "My Open Multiple Dialog";
    } else if (message_name == kFileOpenFolderMessageName) {
      dialog_state_->mode_ = FILE_DIALOG_OPEN_FOLDER;
      title = "My Open Folder Dialog";
    } else if (message_name == kFileSaveMessageName) {
      dialog_state_->mode_ = static_cast<cef_file_dialog_mode_t>(
          FILE_DIALOG_SAVE | FILE_DIALOG_OVERWRITEPROMPT_FLAG);
      title = "My Save Dialog";
    } else {
      NOTREACHED();
      return true;
    }

    if (dialog_state_->mode_ != FILE_DIALOG_OPEN_FOLDER) {
      // Build filters based on mime time.
      accept_filters.push_back("text/*");

      // Build filters based on file extension.
      accept_filters.push_back(".log");
      accept_filters.push_back(".patch");

      // Add specific filters as-is.
      accept_filters.push_back("Document Files|.doc;.odt");
      accept_filters.push_back("Image Files|.png;.jpg;.gif");
      accept_filters.push_back("PDF Files|.pdf");
    }

    dialog_state_->pending_ = true;

    browser->GetHost()->RunFileDialog(
        dialog_state_->mode_, title, dialog_state_->last_file_, accept_filters,
        dialog_state_->last_selected_filter_,
        new DialogCallback(callback, dialog_state_));

    return true;
  }

 private:
  scoped_refptr<DialogState> dialog_state_;

  DISALLOW_COPY_AND_ASSIGN(Handler);
};

}  // namespace

void CreateMessageHandlers(test_runner::MessageHandlerSet& handlers) {
  handlers.insert(new Handler());
}

}  // namespace dialog_test
}  // namespace client
