// Copyright (c) 2011 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 "content/test/render_widget_browsertest.h"

#include "base/basictypes.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/memory/ref_counted_memory.h"
#include "base/stringprintf.h"
#include "content/common/view_messages.h"
#include "content/renderer/render_view_impl.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebSize.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
#include "ui/gfx/codec/jpeg_codec.h"
#include "ui/gfx/size.h"
#include "ui/gfx/surface/transport_dib.h"

const int RenderWidgetTest::kNumBytesPerPixel = 4;
const int RenderWidgetTest::kLargeWidth = 1024;
const int RenderWidgetTest::kLargeHeight = 768;
const int RenderWidgetTest::kSmallWidth = 600;
const int RenderWidgetTest::kSmallHeight = 450;
const int RenderWidgetTest::kTextPositionX = 800;
const int RenderWidgetTest::kTextPositionY = 600;
const uint32 RenderWidgetTest::kRedARGB = 0xFFFF0000;

RenderWidgetTest::RenderWidgetTest() {}

void RenderWidgetTest::ResizeAndPaint(const gfx::Size& page_size,
                                      const gfx::Size& desired_size,
                                      SkBitmap* snapshot) {
  ASSERT_TRUE(snapshot);
  static int g_sequence_num = 0;
  // Use a new sequence number for each DIB.
  scoped_ptr<TransportDIB> pixels(
      TransportDIB::Create(
          page_size.width() * page_size.height() * kNumBytesPerPixel,
          ++g_sequence_num));

  // Go ahead and map the DIB into memory, so that we can use it below
  // to fill tmp_bitmap.  Note that we need to do this before calling
  // OnMsgPaintAtSize, or the last reference to the shared memory will
  // be closed and the handle will no longer be valid.
  scoped_ptr<TransportDIB> mapped_pixels(TransportDIB::Map(pixels->handle()));

  RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_);
  impl->OnMsgPaintAtSize(pixels->handle(), g_sequence_num, page_size,
                         desired_size);
  ProcessPendingMessages();
  const IPC::Message* msg = render_thread_.sink().GetUniqueMessageMatching(
      ViewHostMsg_PaintAtSize_ACK::ID);
  ASSERT_NE(static_cast<IPC::Message*>(NULL), msg);
  ViewHostMsg_PaintAtSize_ACK::Param params;
  ViewHostMsg_PaintAtSize_ACK::Read(msg, &params);
  render_thread_.sink().ClearMessages();
  EXPECT_EQ(g_sequence_num, params.a);
  gfx::Size size = params.b;
  EXPECT_EQ(desired_size, size);

  SkBitmap tmp_bitmap;
  tmp_bitmap.setConfig(SkBitmap::kARGB_8888_Config,
                       size.width(), size.height());
  tmp_bitmap.setPixels(mapped_pixels->memory());
  // Copy the pixels from the TransportDIB object to the given snapshot.
  ASSERT_TRUE(tmp_bitmap.copyTo(snapshot, SkBitmap::kARGB_8888_Config));
}

void RenderWidgetTest::TestResizeAndPaint() {
  // Hello World message is only visible if the view size is at least
  // kTextPositionX x kTextPositionY
  LoadHTML(StringPrintf(
      "<html><body><div style='position: absolute; top: %d; left: "
      "%d; background-color: red;'>Hello World</div></body></html>",
      kTextPositionY, kTextPositionX).c_str());
  WebKit::WebSize old_size = view_->GetWebView()->size();

  SkBitmap bitmap;
  // If we re-size the view to something smaller than where the 'Hello World'
  // text is displayed we won't see any text in the snapshot.  Hence,
  // the snapshot should not contain any red.
  gfx::Size size(kSmallWidth, kSmallHeight);
  ResizeAndPaint(size, size, &bitmap);
  // Make sure that the view has been re-sized to its old size.
  EXPECT_TRUE(old_size == view_->GetWebView()->size());
  EXPECT_EQ(kSmallWidth, bitmap.width());
  EXPECT_EQ(kSmallHeight, bitmap.height());
  EXPECT_FALSE(ImageContainsColor(bitmap, kRedARGB));

  // Since we ask for the view to be re-sized to something larger than where the
  // 'Hello World' text is written the text should be visible in the snapshot.
  // Hence, the snapshot should contain some red.
  size.SetSize(kLargeWidth, kLargeHeight);
  ResizeAndPaint(size, size, &bitmap);
  EXPECT_TRUE(old_size == view_->GetWebView()->size());
  EXPECT_EQ(kLargeWidth, bitmap.width());
  EXPECT_EQ(kLargeHeight, bitmap.height());
  EXPECT_TRUE(ImageContainsColor(bitmap, kRedARGB));

  // Even if the desired size is smaller than where the text is located we
  // should still see the 'Hello World' message since the view size is
  // still large enough.
  ResizeAndPaint(size, gfx::Size(kSmallWidth, kSmallHeight), &bitmap);
  EXPECT_TRUE(old_size == view_->GetWebView()->size());
  EXPECT_EQ(kSmallWidth, bitmap.width());
  EXPECT_EQ(kSmallHeight, bitmap.height());
  EXPECT_TRUE(ImageContainsColor(bitmap, kRedARGB));
}

bool RenderWidgetTest::ImageContainsColor(const SkBitmap& bitmap,
                                          uint32 argb_color) {
  SkAutoLockPixels lock(bitmap);
  bool ready = bitmap.readyToDraw();
  EXPECT_TRUE(ready);
  if (!ready) {
    return false;
  }
  for (int x = 0; x < bitmap.width(); ++x) {
    for (int y = 0; y < bitmap.height(); ++y) {
      if (argb_color == *bitmap.getAddr32(x, y)) {
        return true;
      }
    }
  }
  return false;
}

void RenderWidgetTest::OutputBitmapToFile(const SkBitmap& bitmap,
                                          const FilePath& file_path) {
  scoped_refptr<RefCountedBytes> bitmap_data(new RefCountedBytes());
  SkAutoLockPixels lock(bitmap);
  ASSERT_TRUE(gfx::JPEGCodec::Encode(
      reinterpret_cast<unsigned char*>(bitmap.getAddr32(0, 0)),
      gfx::JPEGCodec::FORMAT_BGRA,
      bitmap.width(),
      bitmap.height(),
      static_cast<int>(bitmap.rowBytes()),
      90 /* quality */,
      &bitmap_data->data()));
  ASSERT_LT(0, file_util::WriteFile(
      file_path,
      reinterpret_cast<const char*>(bitmap_data->front()),
      bitmap_data->size()));
}

TEST_F(RenderWidgetTest, OnMsgPaintAtSize) {
  TestResizeAndPaint();
}
