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

#import "ios/chrome/browser/ui/print/print_controller.h"

#import <MobileCoreServices/UTType.h>
#import <Webkit/Webkit.h>

#include <memory>

#include "base/callback_helpers.h"
#import "base/ios/ios_util.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/mac/bind_objc_block.h"
#include "base/mac/foundation_util.h"
#include "base/memory/ref_counted.h"
#include "base/metrics/user_metrics.h"
#include "base/metrics/user_metrics_action.h"
#include "components/strings/grit/components_strings.h"
#import "ios/chrome/browser/ui/alert_coordinator/alert_coordinator.h"
#import "ios/chrome/browser/ui/alert_coordinator/loading_alert_coordinator.h"
#include "ios/chrome/grit/ios_strings.h"
#include "ios/web/public/web_thread.h"
#import "net/base/mac/url_conversions.h"
#include "net/http/http_response_headers.h"
#include "net/url_request/url_fetcher.h"
#include "net/url_request/url_fetcher_delegate.h"
#include "net/url_request/url_request_context_getter.h"
#include "ui/base/l10n/l10n_util_mac.h"

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

using net::URLFetcher;
using net::URLFetcherDelegate;
using net::URLRequestContextGetter;

@interface PrintController ()

// Presents a UIPrintInteractionController with a default completion handler.
// |isPDF| indicates if |printInteractionController| is being presented to print
// a PDF.
+ (void)displayPrintInteractionController:
            (UIPrintInteractionController*)printInteractionController
                                   forPDF:(BOOL)isPDF;

// Shows a dialog on |viewController| indicating that the print preview is being
// prepared. The dialog will appear only if the download has not completed or
// been cancelled |kPDFDownloadDialogDelay| seconds after this method is called.
- (void)showPDFDownloadingDialog:(UIViewController*)viewController;

// Dismisses the dialog which indicates that the print preview is being
// prepared.
- (void)dismissPDFDownloadingDialog;

// Shows an dialog on |viewController| indicating that there was an error when
// preparing the print preview, and providing the ability to retry. |URL| is the
// URL of the PDF which had an error.
- (void)showPDFDownloadErrorWithURL:(const GURL)URL
                     viewController:(UIViewController*)viewController;

// Handles downloading the file at |URL| and presents dialogs on
// |viewController| if necessary.
- (void)downloadPDFFileWithURL:(const GURL&)URL
                viewController:(UIViewController*)viewController;

// Accesses the result of the PDF download, and if successful, presents the
// AirPrint menu with the downloaded PDF. It also ensures that the
// PDFDownloadingDialog is dismissed, and presents an error dialog on
// |viewController| if the download fails. This method should be called only by
// the URLFetcherDelegate.
- (void)finishedDownloadingPDF:(UIViewController*)viewController;

@end

namespace {

// The MIME type of a PDF file contained in a Web view.
const char kPDFMimeType[] = "application/pdf";

// Delay after downloading begins that the |_PDFDownloadingDialog| appears.
const int64_t kPDFDownloadDialogDelay = 1;

// A delegate for the URLFetcher to tell owning PrintController that the
// download is complete.
class PrintPDFFetcherDelegate : public URLFetcherDelegate {
 public:
  explicit PrintPDFFetcherDelegate(PrintController* owner) : owner_(owner) {}
  void OnURLFetchComplete(const URLFetcher* source) override {
    DCHECK(view_controller_);
    [owner_ finishedDownloadingPDF:view_controller_];
  }

  // The ViewController used to display an error if the download failed.
  void SetViewController(UIViewController* view_controller) {
    view_controller_ = view_controller;
  }

 private:
  __weak PrintController* owner_;
  __weak UIViewController* view_controller_;
  DISALLOW_COPY_AND_ASSIGN(PrintPDFFetcherDelegate);
};
}  // namespace

@implementation PrintController {
  // URLFetcher to download the PDF pointed to by the WKWebView.
  std::unique_ptr<URLFetcher> _fetcher;

  // A delegate to bridge between PrintController and the URLFetcher callback.
  std::unique_ptr<PrintPDFFetcherDelegate> _fetcherDelegate;

  // Context getter required by the URLFetcher.
  scoped_refptr<URLRequestContextGetter> _requestContextGetter;

  // A dialog which indicates that the print preview is being prepared. It
  // offers a cancel button which will cancel the download. It is created when
  // downloading begins and is released when downloading ends (either due to
  // cancellation or completion).
  LoadingAlertCoordinator* _PDFDownloadingDialog;

  // A dialog which indicates that the print preview failed.
  AlertCoordinator* _PDFDownloadingErrorDialog;
}

#pragma mark - Class methods.

+ (void)displayPrintInteractionController:
            (UIPrintInteractionController*)printInteractionController
                                   forPDF:(BOOL)isPDF {
  void (^completionHandler)(UIPrintInteractionController*, BOOL, NSError*) = ^(
      UIPrintInteractionController* printInteractionController, BOOL completed,
      NSError* error) {
    if (error)
      DLOG(ERROR) << "Air printing error: " << error.description;

    // When printing a NSData object given to the
    // UIPrintInteractionController's |printingItem| object, a PDF file
    // representing the NSData object is created in the app's tmp directory
    // by the OS and never deleted. So, this workaround deletes PDF files in
    // tmp now that printing is done. When iOS9 is deprecated, this can
    // be removed since PDFs will no longer need to be downloaded to print,
    // and |printingItem| will no longer be used.
    if (!base::ios::IsRunningOnIOS10OrLater() && isPDF) {
      web::WebThread::PostBlockingPoolTask(
          FROM_HERE, base::BindBlockArc(^{
            NSFileManager* manager = [NSFileManager defaultManager];
            NSString* tempDir = NSTemporaryDirectory();
            NSError* tempDirError = nil;

            // Iterate over files in tmp directory.
            for (NSString* file in
                 [manager contentsOfDirectoryAtPath:tempDir
                                              error:&tempDirError]) {
              // If the file is a PDF file, delete it.
              if ([[file pathExtension] isEqualToString:@"pdf"]) {
                NSError* deletionError = nil;
                NSString* fullFilePath =
                    [tempDir stringByAppendingPathComponent:file];
                BOOL success = [manager removeItemAtPath:fullFilePath
                                                   error:&deletionError];
                if (!success) {
                  DLOG(ERROR) << "AirPrint unable to remove tmp file:" << file
                              << " error: " << deletionError.description;
                }
              }
            }
            if (tempDirError) {
              DLOG(ERROR) << "AirPrint tmp dir access error:"
                          << tempDirError.description;
            }
          }));
    }
  };
  [printInteractionController presentAnimated:YES
                            completionHandler:completionHandler];
}

#pragma mark - Public Methods

- (instancetype)initWithContextGetter:
    (scoped_refptr<net::URLRequestContextGetter>)getter {
  self = [super init];
  if (self) {
    _requestContextGetter = std::move(getter);
    _fetcherDelegate.reset(new PrintPDFFetcherDelegate(self));
  }
  return self;
}

- (instancetype)init {
  NOTREACHED();
  return nil;
}

- (void)printView:(UIView*)view
         withTitle:(NSString*)title
    viewController:(UIViewController*)viewController {
  base::RecordAction(base::UserMetricsAction("MobilePrintMenuAirPrint"));
  UIPrintInteractionController* printInteractionController =
      [UIPrintInteractionController sharedPrintController];
  UIPrintInfo* printInfo = [UIPrintInfo printInfo];
  printInfo.outputType = UIPrintInfoOutputGeneral;
  printInfo.jobName = title;
  printInteractionController.printInfo = printInfo;
  printInteractionController.showsPageRange = YES;

  // Print Formatters do not work for PDFs in iOS9 WKWebView, but do in iOS10.
  // Instead, download the PDF and (eventually) pass it to the
  // UIPrintInteractionController. Remove this workaround and all associated PDF
  // specific code when iOS9 is deprecated.
  BOOL isPDFURL = NO;
  if (!base::ios::IsRunningOnIOS10OrLater() &&
      [view isMemberOfClass:[WKWebView class]]) {
    WKWebView* webView = base::mac::ObjCCastStrict<WKWebView>(view);
    NSURL* URL = webView.URL;
    CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(
        kUTTagClassFilenameExtension,
        (__bridge CFStringRef)[[URL path] pathExtension], NULL);
    if (UTI) {
      CFStringRef MIMEType =
          UTTypeCopyPreferredTagWithClass(UTI, kUTTagClassMIMEType);
      if (MIMEType) {
        isPDFURL =
            [@(kPDFMimeType) isEqualToString:(__bridge NSString*)MIMEType];
        if (isPDFURL) {
          [self downloadPDFFileWithURL:net::GURLWithNSURL(URL)
                        viewController:viewController];
        }
        CFRelease(MIMEType);
      }
      CFRelease(UTI);
    }
  }

  if (!isPDFURL) {
    UIPrintPageRenderer* renderer = [[UIPrintPageRenderer alloc] init];
    [renderer addPrintFormatter:[view viewPrintFormatter]
          startingAtPageAtIndex:0];
    printInteractionController.printPageRenderer = renderer;
    [PrintController
        displayPrintInteractionController:printInteractionController
                                   forPDF:NO];
  }
}

- (void)dismissAnimated:(BOOL)animated {
  _fetcher.reset();
  [self dismissPDFDownloadingDialog];
  [_PDFDownloadingErrorDialog stop];
  _PDFDownloadingErrorDialog = nil;
  [[UIPrintInteractionController sharedPrintController]
      dismissAnimated:animated];
}

#pragma mark - Private Methods

- (void)showPDFDownloadingDialog:(UIViewController*)viewController {
  if (_PDFDownloadingDialog)
    return;

  NSString* title = l10n_util::GetNSString(IDS_IOS_PRINT_PDF_PREPARATION);

  __weak PrintController* weakSelf = self;
  ProceduralBlock cancelHandler = ^{
    PrintController* strongSelf = weakSelf;
    if (strongSelf)
      strongSelf->_fetcher.reset();
  };

  _PDFDownloadingDialog = [[LoadingAlertCoordinator alloc]
      initWithBaseViewController:viewController
                           title:title
                   cancelHandler:cancelHandler];

  dispatch_after(
      dispatch_time(DISPATCH_TIME_NOW, kPDFDownloadDialogDelay * NSEC_PER_SEC),
      dispatch_get_main_queue(), ^{
        PrintController* strongSelf = weakSelf;
        if (!strongSelf)
          return;
        [strongSelf->_PDFDownloadingDialog start];
      });
}

- (void)dismissPDFDownloadingDialog {
  [_PDFDownloadingDialog stop];
  _PDFDownloadingDialog = nil;
}

- (void)showPDFDownloadErrorWithURL:(const GURL)URL
                     viewController:(UIViewController*)viewController {
  NSString* title = l10n_util::GetNSString(IDS_IOS_PRINT_PDF_ERROR_TITLE);
  NSString* message = l10n_util::GetNSString(IDS_IOS_PRINT_PDF_ERROR_SUBTITLE);

  _PDFDownloadingErrorDialog =
      [[AlertCoordinator alloc] initWithBaseViewController:viewController
                                                     title:title
                                                   message:message];

  __weak PrintController* weakSelf = self;

  [_PDFDownloadingErrorDialog
      addItemWithTitle:l10n_util::GetNSString(IDS_IOS_PRINT_PDF_TRY_AGAIN)
                action:^{
                  [weakSelf downloadPDFFileWithURL:URL
                                    viewController:viewController];
                }
                 style:UIAlertActionStyleDefault];

  [_PDFDownloadingErrorDialog
      addItemWithTitle:l10n_util::GetNSString(IDS_CANCEL)
                action:nil
                 style:UIAlertActionStyleCancel];

  [_PDFDownloadingErrorDialog start];
}

- (void)downloadPDFFileWithURL:(const GURL&)URL
                viewController:(UIViewController*)viewController {
  DCHECK(!_fetcher);
  _fetcherDelegate->SetViewController(viewController);
  _fetcher = URLFetcher::Create(URL, URLFetcher::GET, _fetcherDelegate.get());
  _fetcher->SetRequestContext(_requestContextGetter.get());
  _fetcher->Start();
  [self showPDFDownloadingDialog:viewController];
}

- (void)finishedDownloadingPDF:(UIViewController*)viewController {
  [self dismissPDFDownloadingDialog];
  DCHECK(_fetcher);
  base::ScopedClosureRunner fetcherResetter(base::BindBlockArc(^{
    _fetcher.reset();
  }));
  int responseCode = _fetcher->GetResponseCode();
  std::string response;
  std::string MIMEType;
  // If the request is not successful or does not match a PDF
  // MIME type, show an error.
  if (!_fetcher->GetStatus().is_success() || responseCode != 200 ||
      !_fetcher->GetResponseAsString(&response) ||
      !_fetcher->GetResponseHeaders()->GetMimeType(&MIMEType) ||
      MIMEType != kPDFMimeType) {
    [self showPDFDownloadErrorWithURL:_fetcher->GetOriginalURL()
                       viewController:viewController];
    return;
  }
  NSData* data =
      [NSData dataWithBytes:response.c_str() length:response.length()];
  // If the data cannot be printed, show an error.
  if (![UIPrintInteractionController canPrintData:data]) {
    [self showPDFDownloadErrorWithURL:_fetcher->GetOriginalURL()
                       viewController:viewController];
    return;
  }
  UIPrintInteractionController* printInteractionController =
      [UIPrintInteractionController sharedPrintController];
  printInteractionController.printingItem = data;
  [PrintController displayPrintInteractionController:printInteractionController
                                              forPDF:YES];
}

@end
