// 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 "chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.h"

#import <Cocoa/Cocoa.h>

#include "base/files/file_path.h"
#include "base/strings/sys_string_conversions.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "ui/base/clipboard/clipboard.h"

NSString* const kBookmarkDictionaryListPboardType =
    @"BookmarkDictionaryListPboardType";

namespace {

// An unofficial standard pasteboard title type to be provided alongside the
// |NSURLPboardType|.
NSString* const kNSURLTitlePboardType =
    @"public.url-name";

// Pasteboard type used to store profile path to determine which profile
// a set of bookmarks came from.
NSString* const kChromiumProfilePathPboardType =
    @"ChromiumProfilePathPboardType";

// Internal bookmark ID for a bookmark node.  Used only when moving inside
// of one profile.
NSString* const kChromiumBookmarkId =
    @"ChromiumBookmarkId";

// Mac WebKit uses this type, declared in
// WebKit/mac/History/WebURLsWithTitles.h.
NSString* const kCrWebURLsWithTitlesPboardType =
    @"WebURLsWithTitlesPboardType";

// Keys for the type of node in BookmarkDictionaryListPboardType.
NSString* const kWebBookmarkType =
    @"WebBookmarkType";

NSString* const kWebBookmarkTypeList =
    @"WebBookmarkTypeList";

NSString* const kWebBookmarkTypeLeaf =
    @"WebBookmarkTypeLeaf";

void ConvertPlistToElements(NSArray* input,
                            std::vector<BookmarkNodeData::Element>& elements) {
  NSUInteger len = [input count];
  for (NSUInteger i = 0; i < len; ++i) {
    NSDictionary* pboardBookmark = [input objectAtIndex:i];
    scoped_ptr<BookmarkNode> new_node(new BookmarkNode(GURL()));
    int64 node_id =
        [[pboardBookmark objectForKey:kChromiumBookmarkId] longLongValue];
    new_node->set_id(node_id);
    BOOL is_folder = [[pboardBookmark objectForKey:kWebBookmarkType]
        isEqualToString:kWebBookmarkTypeList];
    if (is_folder) {
      new_node->set_type(BookmarkNode::FOLDER);
      NSString* title = [pboardBookmark objectForKey:@"Title"];
      new_node->SetTitle(base::SysNSStringToUTF16(title));
    } else {
      new_node->set_type(BookmarkNode::URL);
      NSDictionary* uriDictionary =
          [pboardBookmark objectForKey:@"URIDictionary"];
      NSString* title = [uriDictionary objectForKey:@"title"];
      NSString* urlString = [pboardBookmark objectForKey:@"URLString"];
      new_node->SetTitle(base::SysNSStringToUTF16(title));
      new_node->set_url(GURL(base::SysNSStringToUTF8(urlString)));
    }
    BookmarkNodeData::Element e = BookmarkNodeData::Element(new_node.get());
    if(is_folder)
      ConvertPlistToElements([pboardBookmark objectForKey:@"Children"],
                             e.children);
    elements.push_back(e);
  }
}

bool ReadBookmarkDictionaryListPboardType(
    NSPasteboard* pb,
    std::vector<BookmarkNodeData::Element>& elements) {
  NSArray* bookmarks =
      [pb propertyListForType:kBookmarkDictionaryListPboardType];
  if (!bookmarks)
    return false;
  ConvertPlistToElements(bookmarks, elements);
  return true;
}

bool ReadWebURLsWithTitlesPboardType(
    NSPasteboard* pb,
    std::vector<BookmarkNodeData::Element>& elements) {
  NSArray* bookmarkPairs =
      [pb propertyListForType:kCrWebURLsWithTitlesPboardType];
  if (![bookmarkPairs isKindOfClass:[NSArray class]])
    return false;

  NSArray* urlsArr = [bookmarkPairs objectAtIndex:0];
  NSArray* titlesArr = [bookmarkPairs objectAtIndex:1];
  if ([urlsArr count] < 1)
    return false;
  if ([urlsArr count] != [titlesArr count])
    return false;

  NSUInteger len = [titlesArr count];
  for (NSUInteger i = 0; i < len; ++i) {
    string16 title = base::SysNSStringToUTF16([titlesArr objectAtIndex:i]);
    std::string url = base::SysNSStringToUTF8([urlsArr objectAtIndex:i]);
    if (!url.empty()) {
      BookmarkNodeData::Element element;
      element.is_url = true;
      element.url = GURL(url);
      element.title = title;
      elements.push_back(element);
    }
  }
  return true;
}

bool ReadNSURLPboardType(NSPasteboard* pb,
                         std::vector<BookmarkNodeData::Element>& elements) {
  NSURL* url = [NSURL URLFromPasteboard:pb];
  if (url == nil)
    return false;

  std::string urlString = base::SysNSStringToUTF8([url absoluteString]);
  NSString* title = [pb stringForType:kNSURLTitlePboardType];
  if (!title)
    title = [pb stringForType:NSStringPboardType];

  BookmarkNodeData::Element element;
  element.is_url = true;
  element.url = GURL(urlString);
  element.title = base::SysNSStringToUTF16(title);
  elements.push_back(element);
  return true;
}

NSArray* GetPlistForBookmarkList(
    const std::vector<BookmarkNodeData::Element>& elements) {
  NSMutableArray* plist = [NSMutableArray array];
  for (size_t i = 0; i < elements.size(); ++i) {
    BookmarkNodeData::Element element = elements[i];
    if (element.is_url) {
      NSString* title = base::SysUTF16ToNSString(element.title);
      NSString* url = base::SysUTF8ToNSString(element.url.spec());
      int64 elementId = element.id();
      NSNumber* idNum = [NSNumber numberWithLongLong:elementId];
      NSDictionary* uriDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
              title, @"title", nil];
      NSDictionary* object = [NSDictionary dictionaryWithObjectsAndKeys:
          uriDictionary, @"URIDictionary",
          url, @"URLString",
          kWebBookmarkTypeLeaf, kWebBookmarkType,
          idNum, kChromiumBookmarkId,
          nil];
      [plist addObject:object];
    } else {
      NSString* title = base::SysUTF16ToNSString(element.title);
      NSArray* children = GetPlistForBookmarkList(element.children);
      int64 elementId = element.id();
      NSNumber* idNum = [NSNumber numberWithLongLong:elementId];
      NSDictionary* object = [NSDictionary dictionaryWithObjectsAndKeys:
          title, @"Title",
          children, @"Children",
          kWebBookmarkTypeList, kWebBookmarkType,
          idNum, kChromiumBookmarkId,
          nil];
      [plist addObject:object];
    }
  }
  return plist;
}

void WriteBookmarkDictionaryListPboardType(
    NSPasteboard* pb,
    const std::vector<BookmarkNodeData::Element>& elements) {
  NSArray* plist = GetPlistForBookmarkList(elements);
  [pb setPropertyList:plist forType:kBookmarkDictionaryListPboardType];
}

void FillFlattenedArraysForBookmarks(
    const std::vector<BookmarkNodeData::Element>& elements,
    NSMutableArray* titles, NSMutableArray* urls) {
  for (size_t i = 0; i < elements.size(); ++i) {
    BookmarkNodeData::Element element = elements[i];
    if (element.is_url) {
      NSString* title = base::SysUTF16ToNSString(element.title);
      NSString* url = base::SysUTF8ToNSString(element.url.spec());
      [titles addObject:title];
      [urls addObject:url];
    } else {
      FillFlattenedArraysForBookmarks(element.children, titles, urls);
    }
  }
}

void WriteSimplifiedBookmarkTypes(NSPasteboard* pb,
    const std::vector<BookmarkNodeData::Element>& elements) {
  NSMutableArray* titles = [NSMutableArray array];
  NSMutableArray* urls = [NSMutableArray array];
  FillFlattenedArraysForBookmarks(elements, titles, urls);

  // These bookmark types only act on urls, not folders.
  if ([urls count] < 1)
    return;

  // Write WebURLsWithTitlesPboardType.
  [pb setPropertyList:[NSArray arrayWithObjects:urls, titles, nil]
              forType:kCrWebURLsWithTitlesPboardType];

  // Write NSStringPboardType.
  [pb setString:[urls componentsJoinedByString:@"\n"]
        forType:NSStringPboardType];

  // Write NSURLPboardType (with title).
  NSURL* url = [NSURL URLWithString:[urls objectAtIndex:0]];
  [url writeToPasteboard:pb];
  NSString* titleString = [titles objectAtIndex:0];
  [pb setString:titleString forType:kNSURLTitlePboardType];
}

NSPasteboard* PasteboardFromType(
    bookmark_pasteboard_helper_mac::PasteboardType type) {
  NSString* type_string = nil;
  switch (type) {
    case bookmark_pasteboard_helper_mac::kCopyPastePasteboard:
      type_string = NSGeneralPboard;
      break;
    case bookmark_pasteboard_helper_mac::kDragPasteboard:
      type_string = NSDragPboard;
      break;
  }

  return [NSPasteboard pasteboardWithName:type_string];
}

}  // namespace

namespace bookmark_pasteboard_helper_mac {

void WriteToPasteboard(PasteboardType type,
                       const std::vector<BookmarkNodeData::Element>& elements,
                       const base::FilePath& profile_path) {
  if (elements.empty())
    return;

  NSPasteboard* pb = PasteboardFromType(type);

  NSArray* types = [NSArray arrayWithObjects:kBookmarkDictionaryListPboardType,
                                             kCrWebURLsWithTitlesPboardType,
                                             NSStringPboardType,
                                             NSURLPboardType,
                                             kNSURLTitlePboardType,
                                             kChromiumProfilePathPboardType,
                                             nil];
  [pb declareTypes:types owner:nil];
  [pb setString:base::SysUTF8ToNSString(profile_path.value())
        forType:kChromiumProfilePathPboardType];
  WriteBookmarkDictionaryListPboardType(pb, elements);
  WriteSimplifiedBookmarkTypes(pb, elements);
}

bool ReadFromPasteboard(PasteboardType type,
                        std::vector<BookmarkNodeData::Element>& elements,
                        base::FilePath* profile_path) {
  NSPasteboard* pb = PasteboardFromType(type);

  elements.clear();
  NSString* profile = [pb stringForType:kChromiumProfilePathPboardType];
  *profile_path = base::FilePath(base::SysNSStringToUTF8(profile));
  return ReadBookmarkDictionaryListPboardType(pb, elements) ||
         ReadWebURLsWithTitlesPboardType(pb, elements) ||
         ReadNSURLPboardType(pb, elements);
}

bool PasteboardContainsBookmarks(PasteboardType type) {
  NSPasteboard* pb = PasteboardFromType(type);

  NSArray* availableTypes =
      [NSArray arrayWithObjects:kBookmarkDictionaryListPboardType,
                                kCrWebURLsWithTitlesPboardType,
                                NSURLPboardType,
                                nil];
  return [pb availableTypeFromArray:availableTypes] != nil;
}

}  // namespace bookmark_pasteboard_helper_mac
