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

#include "printing/printing_context_android.h"

#include <stdint.h>

#include <memory>
#include <utility>
#include <vector>

#include "base/android/jni_android.h"
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
#include "base/files/file.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "base/values.h"
#include "printing/metafile.h"
#include "printing/mojom/print.mojom.h"
#include "printing/print_job_constants.h"
#include "printing/printing_jni_headers/PrintingContext_jni.h"
#include "printing/units.h"
#include "third_party/icu/source/i18n/unicode/ulocdata.h"
#include "ui/android/window_android.h"

using base::android::JavaParamRef;
using base::android::JavaRef;
using base::android::ScopedJavaLocalRef;

namespace printing {

namespace {

// Sets the page sizes for a `PrintSettings` object.  `width` and `height`
// arguments should be in device units.
void SetSizes(PrintSettings* settings, int dpi, int width, int height) {
  gfx::Size physical_size_device_units(width, height);
  // Assume full page is printable for now.
  gfx::Rect printable_area_device_units(0, 0, width, height);

  settings->set_dpi(dpi);
  settings->SetPrinterPrintableArea(physical_size_device_units,
                                    printable_area_device_units, false);
}

void GetPageRanges(JNIEnv* env,
                   const JavaRef<jintArray>& int_arr,
                   PageRanges* range_vector) {
  std::vector<int> pages;
  base::android::JavaIntArrayToIntVector(env, int_arr, &pages);
  for (int page : pages) {
    PageRange range;
    range.from = page;
    range.to = page;
    range_vector->push_back(range);
  }
}

}  // namespace

// static
std::unique_ptr<PrintingContext> PrintingContext::CreateImpl(
    Delegate* delegate,
    bool skip_system_calls) {
  DCHECK(!skip_system_calls);
  return std::make_unique<PrintingContextAndroid>(delegate);
}

// static
void PrintingContextAndroid::PdfWritingDone(int page_count) {
  JNIEnv* env = base::android::AttachCurrentThread();
  Java_PrintingContext_pdfWritingDone(env, page_count);
}

// static
void PrintingContextAndroid::SetPendingPrint(
    ui::WindowAndroid* window,
    const ScopedJavaLocalRef<jobject>& printable,
    int render_process_id,
    int render_frame_id) {
  JNIEnv* env = base::android::AttachCurrentThread();
  Java_PrintingContext_setPendingPrint(env, window->GetJavaObject(), printable,
                                       render_process_id, render_frame_id);
}

PrintingContextAndroid::PrintingContextAndroid(Delegate* delegate)
    : PrintingContext(delegate) {
  // The constructor is run in the IO thread.
}

PrintingContextAndroid::~PrintingContextAndroid() {}

void PrintingContextAndroid::AskUserForSettings(
    int max_pages,
    bool has_selection,
    bool is_scripted,
    PrintSettingsCallback callback) {
  // This method is always run in the UI thread.
  callback_ = std::move(callback);

  JNIEnv* env = base::android::AttachCurrentThread();
  if (j_printing_context_.is_null()) {
    j_printing_context_.Reset(
        Java_PrintingContext_create(env, reinterpret_cast<intptr_t>(this)));
  }

  if (is_scripted) {
    Java_PrintingContext_showPrintDialog(env, j_printing_context_);
  } else {
    Java_PrintingContext_askUserForSettings(env, j_printing_context_,
                                            max_pages);
  }
}

void PrintingContextAndroid::AskUserForSettingsReply(
    JNIEnv* env,
    const JavaParamRef<jobject>& obj,
    jboolean success) {
  DCHECK(callback_);
  if (!success) {
    // TODO(cimamoglu): Differentiate between `kFailed` And `kCancel`.
    std::move(callback_).Run(mojom::ResultCode::kFailed);
    return;
  }

  // We use device name variable to store the file descriptor.  This is hacky
  // but necessary. Since device name is not necessary for the upstream
  // printing code for Android, this is harmless.
  // TODO(thestig): See if the call to set_device_name() can be removed.
  fd_ = Java_PrintingContext_getFileDescriptor(env, j_printing_context_);
  DCHECK(is_file_descriptor_valid());
  settings_->set_device_name(base::NumberToString16(fd_));

  ScopedJavaLocalRef<jintArray> intArr =
      Java_PrintingContext_getPages(env, j_printing_context_);
  if (!intArr.is_null()) {
    PageRanges range_vector;
    GetPageRanges(env, intArr, &range_vector);
    settings_->set_ranges(range_vector);
  }

  int dpi = Java_PrintingContext_getDpi(env, j_printing_context_);
  int width = Java_PrintingContext_getWidth(env, j_printing_context_);
  int height = Java_PrintingContext_getHeight(env, j_printing_context_);
  width = ConvertUnit(width, kMilsPerInch, dpi);
  height = ConvertUnit(height, kMilsPerInch, dpi);
  SetSizes(settings_.get(), dpi, width, height);

  std::move(callback_).Run(mojom::ResultCode::kSuccess);
}

void PrintingContextAndroid::ShowSystemDialogDone(
    JNIEnv* env,
    const JavaParamRef<jobject>& obj) {
  DCHECK(callback_);
  // Settings are not updated, callback is called only to unblock javascript.
  std::move(callback_).Run(mojom::ResultCode::kCanceled);
}

mojom::ResultCode PrintingContextAndroid::UseDefaultSettings() {
  DCHECK(!in_print_job_);

  ResetSettings();
  settings_->set_dpi(kDefaultPdfDpi);
  gfx::Size physical_size = GetPdfPaperSizeDeviceUnits();
  SetSizes(settings_.get(), kDefaultPdfDpi, physical_size.width(),
           physical_size.height());
  return mojom::ResultCode::kSuccess;
}

gfx::Size PrintingContextAndroid::GetPdfPaperSizeDeviceUnits() {
  // NOTE: This implementation is the same as in PrintingContextNoSystemDialog.
  int32_t width = 0;
  int32_t height = 0;
  UErrorCode error = U_ZERO_ERROR;
  ulocdata_getPaperSize(delegate_->GetAppLocale().c_str(), &height, &width,
                        &error);
  if (error > U_ZERO_ERROR) {
    // If the call failed, assume a paper size of 8.5 x 11 inches.
    LOG(WARNING) << "ulocdata_getPaperSize failed, using 8.5 x 11, error: "
                 << error;
    width =
        static_cast<int>(kLetterWidthInch * settings_->device_units_per_inch());
    height = static_cast<int>(kLetterHeightInch *
                              settings_->device_units_per_inch());
  } else {
    // ulocdata_getPaperSize returns the width and height in mm.
    // Convert this to pixels based on the dpi.
    float multiplier = settings_->device_units_per_inch() / kMicronsPerMil;
    width *= multiplier;
    height *= multiplier;
  }
  return gfx::Size(width, height);
}

mojom::ResultCode PrintingContextAndroid::UpdatePrinterSettings(
    const PrinterSettings& printer_settings) {
  DCHECK(!printer_settings.show_system_dialog);
  DCHECK(!in_print_job_);

  // Intentional No-op.

  return mojom::ResultCode::kSuccess;
}

mojom::ResultCode PrintingContextAndroid::NewDocument(
    const std::u16string& document_name) {
  DCHECK(!in_print_job_);
  in_print_job_ = true;

  return mojom::ResultCode::kSuccess;
}

mojom::ResultCode PrintingContextAndroid::PrintDocument(
    const MetafilePlayer& metafile,
    const PrintSettings& settings,
    uint32_t num_pages) {
  if (abort_printing_)
    return mojom::ResultCode::kCanceled;
  DCHECK(in_print_job_);
  DCHECK(is_file_descriptor_valid());

  return metafile.SaveToFileDescriptor(fd_) ? mojom::ResultCode::kSuccess
                                            : mojom::ResultCode::kFailed;
}

mojom::ResultCode PrintingContextAndroid::DocumentDone() {
  if (abort_printing_)
    return mojom::ResultCode::kCanceled;
  DCHECK(in_print_job_);

  ResetSettings();
  return mojom::ResultCode::kSuccess;
}

void PrintingContextAndroid::Cancel() {
  abort_printing_ = true;
  in_print_job_ = false;
}

void PrintingContextAndroid::ReleaseContext() {
  // Intentional No-op.
}

printing::NativeDrawingContext PrintingContextAndroid::context() const {
  // Intentional No-op.
  return nullptr;
}

}  // namespace printing
