// Copyright 2013 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 <stdio.h>

#include <string>
#include <utility>

#include "base/command_line.h"
#include "base/logging.h"
#include "ui/display/display.h"
#include "ui/display/display_switches.h"
#include "ui/display/manager/display_layout_store.h"
#include "ui/display/manager/display_manager_utilities.h"
#include "ui/display/types/display_constants.h"

namespace display {

DisplayLayoutStore::DisplayLayoutStore()
    : default_display_placement_(DisplayPlacement::RIGHT, 0) {
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  if (command_line->HasSwitch(switches::kSecondaryDisplayLayout)) {
    std::string value =
        command_line->GetSwitchValueASCII(switches::kSecondaryDisplayLayout);
    char layout;
    int offset = 0;
    if (sscanf(value.c_str(), "%c,%d", &layout, &offset) == 2) {
      if (layout == 't')
        default_display_placement_.position = DisplayPlacement::TOP;
      else if (layout == 'b')
        default_display_placement_.position = DisplayPlacement::BOTTOM;
      else if (layout == 'r')
        default_display_placement_.position = DisplayPlacement::RIGHT;
      else if (layout == 'l')
        default_display_placement_.position = DisplayPlacement::LEFT;
      default_display_placement_.offset = offset;
    }
  }
}

DisplayLayoutStore::~DisplayLayoutStore() {}

void DisplayLayoutStore::SetDefaultDisplayPlacement(
    const DisplayPlacement& placement) {
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  if (!command_line->HasSwitch(switches::kSecondaryDisplayLayout))
    default_display_placement_ = placement;
}

void DisplayLayoutStore::RegisterLayoutForDisplayIdList(
    const DisplayIdList& list,
    std::unique_ptr<DisplayLayout> layout) {
  // m50/51 dev/beta channel may have bad layout data saved in local state.
  // TODO(oshima): Consider removing this after m53.
  if (list.size() == 2 && layout->placement_list.size() > 1)
    return;

  // Do not overwrite the valid data with old invalid date.
  if (layouts_.count(list) && !CompareDisplayIds(list[0], list[1]))
    return;

  // Old data may not have the display_id/parent_display_id.
  // Guess these values based on the saved primary_id.
  if (layout->placement_list.size() >= 1 &&
      layout->placement_list[0].display_id == kInvalidDisplayId) {
    if (layout->primary_id == list[1]) {
      layout->placement_list[0].display_id = list[0];
      layout->placement_list[0].parent_display_id = list[1];
    } else {
      layout->placement_list[0].display_id = list[1];
      layout->placement_list[0].parent_display_id = list[0];
    }
  }

  if (!DisplayLayout::Validate(list, *layout.get())) {
    NOTREACHED() << "Attempting to register an invalid layout: ids="
                 << DisplayIdListToString(list)
                 << ", layout=" << layout->ToString();
    // We never allow to register an invalid layout, instead, we revert back to
    // a default layout.
    CreateDefaultDisplayLayout(list);
    return;
  }

  layouts_[list] = std::move(layout);
}

const DisplayLayout& DisplayLayoutStore::GetRegisteredDisplayLayout(
    const DisplayIdList& list) {
  DCHECK_GT(list.size(), 1u);
  const auto iter = layouts_.find(list);
  const DisplayLayout* layout = iter != layouts_.end()
                                    ? iter->second.get()
                                    : CreateDefaultDisplayLayout(list);
  DCHECK(DisplayLayout::Validate(list, *layout)) << layout->ToString();
  DCHECK_NE(layout->primary_id, kInvalidDisplayId);
  return *layout;
}

void DisplayLayoutStore::UpdateDefaultUnified(const DisplayIdList& list,
                                              bool default_unified) {
  DCHECK(layouts_.find(list) != layouts_.end());
  if (layouts_.find(list) == layouts_.end())
    CreateDefaultDisplayLayout(list);

  layouts_[list]->default_unified = default_unified;
}

DisplayLayout* DisplayLayoutStore::CreateDefaultDisplayLayout(
    const DisplayIdList& list) {
  std::unique_ptr<DisplayLayout> layout(new DisplayLayout);
  // The first display is the primary by default.
  layout->primary_id = list[0];
  layout->placement_list.clear();
  for (size_t i = 0; i < list.size() - 1; i++) {
    DisplayPlacement placement(default_display_placement_);
    placement.display_id = list[i + 1];
    placement.parent_display_id = list[i];
    layout->placement_list.push_back(placement);
  }
  layouts_[list] = std::move(layout);
  auto iter = layouts_.find(list);
  return iter->second.get();
}

}  // namespace display
