// Copyright (c) 2010 The Chromium OS 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 <vector>

#include <gflags/gflags.h>
#include <gtest/gtest.h>

#include "base/command_line.h"
#include "base/logging.h"
#include "base/string_util.h"
#include "monitor_reconfig/resolution_selector.h"

DEFINE_bool(logtostderr, false,
            "Print debugging messages to stderr (suppressed otherwise)");

namespace monitor_reconfig {

using std::string;
using std::vector;

class ResolutionSelectorTest : public ::testing::Test {
 protected:
  virtual void SetUp() {}

  // Add a mode to |lcd_modes_|.
  void AddLcdMode(int width, int height) {
    lcd_modes_.push_back(
        ResolutionSelector::Mode(
            width, height, StringPrintf("%dx%d", width, height)));
  }

  // Add a mode to |external_modes_|.
  void AddExternalMode(int width, int height) {
    external_modes_.push_back(
        ResolutionSelector::Mode(
            width, height, StringPrintf("%dx%d", width, height)));
  }

  // Ask |selector_| for the best resolutions and store them in
  // |lcd_resolution_|, |external_resolution_|, and |screen_resolution_|.
  // The return value from |FindBestResolutions()| is returned.
  bool GetResolutions() {
    return selector_.FindBestResolutions(lcd_modes_,
                                         external_modes_,
                                         &lcd_resolution_,
                                         &external_resolution_,
                                         &screen_resolution_);
  }

  ResolutionSelector selector_;

  vector<ResolutionSelector::Mode> lcd_modes_;
  vector<ResolutionSelector::Mode> external_modes_;

  string lcd_resolution_;
  string external_resolution_;
  string screen_resolution_;
};

// We should use the LCD's max resolution when there's no external output
// connected.
TEST_F(ResolutionSelectorTest, NoExternalOutput) {
  AddLcdMode(1024, 768);
  AddLcdMode(800, 600);
  ASSERT_TRUE(GetResolutions());
  EXPECT_EQ("1024x768", lcd_resolution_);
  EXPECT_EQ("", external_resolution_);
  EXPECT_EQ("1024x768", screen_resolution_);
}

// When both outputs have the same max resolution, we should use it.
TEST_F(ResolutionSelectorTest, MatchingTopResolutions) {
  AddLcdMode(1024, 768);
  AddLcdMode(800, 600);
  AddExternalMode(1024, 768);
  AddExternalMode(800, 600);
  ASSERT_TRUE(GetResolutions());
  EXPECT_EQ("1024x768", lcd_resolution_);
  EXPECT_EQ("1024x768", external_resolution_);
  EXPECT_EQ("1024x768", screen_resolution_);
}

// We should use the highest shared resolution when the LCD has the higher
// max resolution.
TEST_F(ResolutionSelectorTest, LcdHasHigherResolution) {
  AddLcdMode(1024, 768);
  AddLcdMode(800, 600);
  AddLcdMode(640, 480);
  AddExternalMode(800, 600);
  AddExternalMode(640, 480);
  ASSERT_TRUE(GetResolutions());
  EXPECT_EQ("800x600", lcd_resolution_);
  EXPECT_EQ("800x600", external_resolution_);
  EXPECT_EQ("800x600", screen_resolution_);
}

// We should use the highest shared resolution when the external output has
// the higher max resolution.
TEST_F(ResolutionSelectorTest, ExternalHasHigherResolution) {
  AddLcdMode(800, 600);
  AddLcdMode(640, 480);
  AddExternalMode(1024, 768);
  AddExternalMode(800, 600);
  AddExternalMode(640, 480);
  ASSERT_TRUE(GetResolutions());
  EXPECT_EQ("800x600", lcd_resolution_);
  EXPECT_EQ("800x600", external_resolution_);
  EXPECT_EQ("800x600", screen_resolution_);
}

// When the maximum resolution offered by the two outputs is different, we
// should use the max resolution from the lower-res output.
TEST_F(ResolutionSelectorTest, MismatchedMaxResolution) {
  AddLcdMode(1024, 600);
  AddLcdMode(800, 600);
  AddExternalMode(1280, 720);
  AddExternalMode(1024, 768);
  AddExternalMode(800, 600);
  ASSERT_TRUE(GetResolutions());
  EXPECT_EQ("1024x600", lcd_resolution_);
  EXPECT_EQ("1024x768", external_resolution_);
  EXPECT_EQ("1024x600", screen_resolution_);
}

// When the external output is large enough that we think it's a monitor,
// we should just use its maximum resolution instead of trying to find a
// size that'll also work for the LCD output.
TEST_F(ResolutionSelectorTest, ExternalOutputIsMonitor) {
  AddLcdMode(1024, 768);
  AddLcdMode(800, 600);
  AddExternalMode(1600, 1200);
  AddExternalMode(1280, 960);
  AddExternalMode(1024, 768);
  ASSERT_GE(external_modes_[0].width * external_modes_[0].height,
            ResolutionSelector::kMaxProjectorPixels);
  ASSERT_TRUE(GetResolutions());
  EXPECT_EQ("1024x768", lcd_resolution_);
  EXPECT_EQ("1600x1200", external_resolution_);
  EXPECT_EQ("1600x1200", screen_resolution_);
}

// We should just fail if there's no common resolution between the two
// outputs.
TEST_F(ResolutionSelectorTest, FailIfNoCommonResolution) {
  AddLcdMode(1024, 768);
  AddExternalMode(1280, 600);
  EXPECT_FALSE(GetResolutions());
}

}  // namespace monitor_reconfig

int main(int argc, char** argv) {
  google::ParseCommandLineFlags(&argc, &argv, true);
  CommandLine::Init(argc, argv);
  logging::InitLogging(NULL,
                       FLAGS_logtostderr ?
                         logging::LOG_ONLY_TO_SYSTEM_DEBUG_LOG :
                         logging::LOG_NONE,
                       logging::DONT_LOCK_LOG_FILE,
                       logging::APPEND_TO_OLD_LOG_FILE);
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
