// Copyright (c) 2012 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 "ppapi/proxy/file_chooser_resource.h"

#include "base/bind.h"
#include "base/strings/string_split.h"
#include "ipc/ipc_message.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/proxy/dispatch_reply_message.h"
#include "ppapi/proxy/file_ref_resource.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/shared_impl/var.h"

namespace ppapi {
namespace proxy {

FileChooserResource::FileChooserResource(Connection connection,
                                         PP_Instance instance,
                                         PP_FileChooserMode_Dev mode,
                                         const std::string& accept_types)
    : PluginResource(connection, instance),
      mode_(mode) {
  PopulateAcceptTypes(accept_types, &accept_types_);
}

FileChooserResource::~FileChooserResource() {
}

thunk::PPB_FileChooser_API* FileChooserResource::AsPPB_FileChooser_API() {
  return this;
}

int32_t FileChooserResource::Show(const PP_ArrayOutput& output,
                                  scoped_refptr<TrackedCallback> callback) {
  return ShowWithoutUserGesture(PP_FALSE, PP_MakeUndefined(), output, callback);
}

int32_t FileChooserResource::ShowWithoutUserGesture(
    PP_Bool save_as,
    PP_Var suggested_file_name,
    const PP_ArrayOutput& output,
    scoped_refptr<TrackedCallback> callback) {
  int32_t result = ShowInternal(save_as, suggested_file_name, callback);
  if (result == PP_OK_COMPLETIONPENDING)
    output_.set_pp_array_output(output);
  return result;
}

int32_t FileChooserResource::Show0_5(scoped_refptr<TrackedCallback> callback) {
  return ShowInternal(PP_FALSE, PP_MakeUndefined(), callback);
}

PP_Resource FileChooserResource::GetNextChosenFile() {
 if (file_queue_.empty())
    return 0;

  // Return the next resource in the queue. It will already have been addrefed
  // (they're currently owned by the FileChooser) and returning it transfers
  // ownership of that reference to the plugin.
  PP_Resource next = file_queue_.front();
  file_queue_.pop();
  return next;
}

int32_t FileChooserResource::ShowWithoutUserGesture0_5(
    PP_Bool save_as,
    PP_Var suggested_file_name,
    scoped_refptr<TrackedCallback> callback) {
  return ShowInternal(save_as, suggested_file_name, callback);
}

// static
void FileChooserResource::PopulateAcceptTypes(
    const std::string& input,
    std::vector<std::string>* output) {
  if (input.empty())
    return;

  std::vector<std::string> type_list;
  base::SplitString(input, ',', &type_list);
  output->reserve(type_list.size());

  for (size_t i = 0; i < type_list.size(); ++i) {
    std::string type = type_list[i];
    base::TrimWhitespaceASCII(type, base::TRIM_ALL, &type);

    // If the type is a single character, it definitely cannot be valid. In the
    // case of a file extension it would be a single ".". In the case of a MIME
    // type it would just be a "/".
    if (type.length() < 2)
      continue;
    if (type.find_first_of('/') == std::string::npos && type[0] != '.')
      continue;
    StringToLowerASCII(&type);
    output->push_back(type);
  }
}

void FileChooserResource::OnPluginMsgShowReply(
    const ResourceMessageReplyParams& params,
    const std::vector<FileRefCreateInfo>& chosen_files) {
  if (output_.is_valid()) {
    // Using v0.6 of the API with the output array.
    std::vector<PP_Resource> files;
    for (size_t i = 0; i < chosen_files.size(); i++) {
      files.push_back(FileRefResource::CreateFileRef(
          connection(),
          pp_instance(),
          chosen_files[i]));
    }
    output_.StoreResourceVector(files);
  } else {
    // Convert each of the passed in file infos to resources. These will be
    // owned by the FileChooser object until they're passed to the plugin.
    DCHECK(file_queue_.empty());
    for (size_t i = 0; i < chosen_files.size(); i++) {
      file_queue_.push(FileRefResource::CreateFileRef(
          connection(),
          pp_instance(),
          chosen_files[i]));
    }
  }

  // Notify the plugin of the new data.
  callback_->Run(params.result());
  // DANGER: May delete |this|!
}

int32_t FileChooserResource::ShowInternal(
    PP_Bool save_as,
    const PP_Var& suggested_file_name,
    scoped_refptr<TrackedCallback> callback) {
  if (TrackedCallback::IsPending(callback_))
    return PP_ERROR_INPROGRESS;

  if (!sent_create_to_renderer())
    SendCreate(RENDERER, PpapiHostMsg_FileChooser_Create());

  callback_ = callback;
  StringVar* sugg_str = StringVar::FromPPVar(suggested_file_name);

  PpapiHostMsg_FileChooser_Show msg(
        PP_ToBool(save_as),
        mode_ == PP_FILECHOOSERMODE_OPENMULTIPLE,
        sugg_str ? sugg_str->value() : std::string(),
        accept_types_);
  Call<PpapiPluginMsg_FileChooser_ShowReply>(RENDERER, msg,
      base::Bind(&FileChooserResource::OnPluginMsgShowReply, this));
  return PP_OK_COMPLETIONPENDING;
}

}  // namespace proxy
}  // namespace ppapi
