// 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 "remoting/host/clipboard.h"

#import <Cocoa/Cocoa.h>
#include <stdint.h>

#include <memory>
#include <utility>

#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/strings/sys_string_conversions.h"
#include "base/timer/timer.h"
#include "remoting/base/constants.h"
#include "remoting/base/util.h"
#include "remoting/proto/event.pb.h"
#include "remoting/protocol/clipboard_stub.h"

namespace {

// Clipboard polling interval in milliseconds.
const int64_t kClipboardPollingIntervalMs = 500;

} // namespace

namespace remoting {

class ClipboardMac : public Clipboard {
 public:
  ClipboardMac();
  ~ClipboardMac() override;

  void Start(
      std::unique_ptr<protocol::ClipboardStub> client_clipboard) override;
  void InjectClipboardEvent(const protocol::ClipboardEvent& event) override;

 private:
  void CheckClipboardForChanges();

  std::unique_ptr<protocol::ClipboardStub> client_clipboard_;
  std::unique_ptr<base::RepeatingTimer> clipboard_polling_timer_;
  NSInteger current_change_count_;

  DISALLOW_COPY_AND_ASSIGN(ClipboardMac);
};

ClipboardMac::ClipboardMac() : current_change_count_(0) {}

ClipboardMac::~ClipboardMac() {}

void ClipboardMac::Start(
    std::unique_ptr<protocol::ClipboardStub> client_clipboard) {
  client_clipboard_ = std::move(client_clipboard);

  // Synchronize local change-count with the pasteboard's. The change-count is
  // used to detect clipboard changes.
  current_change_count_ = [[NSPasteboard generalPasteboard] changeCount];

  // OS X doesn't provide a clipboard-changed notification. The only way to
  // detect clipboard changes is by polling.
  clipboard_polling_timer_.reset(new base::RepeatingTimer());
  clipboard_polling_timer_->Start(FROM_HERE,
      base::TimeDelta::FromMilliseconds(kClipboardPollingIntervalMs),
      this, &ClipboardMac::CheckClipboardForChanges);
}

void ClipboardMac::InjectClipboardEvent(const protocol::ClipboardEvent& event) {
  // Currently we only handle UTF-8 text.
  if (event.mime_type().compare(kMimeTypeTextUtf8) != 0)
    return;
  if (!StringIsUtf8(event.data().c_str(), event.data().length())) {
    LOG(ERROR) << "ClipboardEvent data is not UTF-8 encoded.";
    return;
  }

  // Write text to clipboard.
  NSString* text = base::SysUTF8ToNSString(event.data());
  NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
  [pasteboard clearContents];
  [pasteboard writeObjects:@[ text ]];

  // Update local change-count to prevent this change from being picked up by
  // CheckClipboardForChanges.
  current_change_count_ = [[NSPasteboard generalPasteboard] changeCount];
}

void ClipboardMac::CheckClipboardForChanges() {
  NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
  NSInteger change_count = [pasteboard changeCount];
  if (change_count == current_change_count_) {
    return;
  }
  current_change_count_ = change_count;

  NSArray* objects =
      [pasteboard readObjectsForClasses:@[ [NSString class] ] options:0];
  if (![objects count]) {
    return;
  }

  protocol::ClipboardEvent event;
  event.set_mime_type(kMimeTypeTextUtf8);
  event.set_data(base::SysNSStringToUTF8([objects lastObject]));
  client_clipboard_->InjectClipboardEvent(event);
}

std::unique_ptr<Clipboard> Clipboard::Create() {
  return base::WrapUnique(new ClipboardMac());
}

}  // namespace remoting
