// Copyright 2016 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 "services/gfx/compositor/graph/scene_content.h"

#include <ostream>

#include "base/logging.h"
#include "services/gfx/compositor/graph/scene_def.h"

namespace compositor {

SceneContent::SceneContent(const SceneLabel& label,
                           uint32_t version,
                           int64_t presentation_time,
                           size_t max_resources,
                           size_t max_nodes)
    : label_(label),
      version_(version),
      presentation_time_(presentation_time),
      resources_(max_resources),
      nodes_(max_nodes) {}

SceneContent::~SceneContent() {}

bool SceneContent::MatchesVersion(uint32_t requested_version) const {
  return requested_version == mojo::gfx::composition::kSceneVersionNone ||
         requested_version == version_ ||
         version_ == mojo::gfx::composition::kSceneVersionNone;
}

void SceneContent::Paint(const Snapshot* snapshot, SkCanvas* canvas) const {
  const Node* root = GetRootNodeIfExists();
  if (root)
    root->Paint(this, snapshot, canvas);
}

bool SceneContent::HitTest(
    const Snapshot* snapshot,
    const SkPoint& scene_point,
    const SkMatrix44& global_to_scene_transform,
    mojo::gfx::composition::SceneHitPtr* out_scene_hit) const {
  DCHECK(snapshot);
  DCHECK(out_scene_hit);

  const Node* root = GetRootNodeIfExists();
  if (!root)
    return false;

  mojo::Array<mojo::gfx::composition::HitPtr> hits;
  bool opaque = root->HitTest(this, snapshot, scene_point,
                              global_to_scene_transform, &hits);
  if (hits.size()) {
    auto scene_hit = mojo::gfx::composition::SceneHit::New();
    scene_hit->scene_token = mojo::gfx::composition::SceneToken::New();
    scene_hit->scene_token->value = label_.token();
    scene_hit->scene_version = version_;
    scene_hit->hits = hits.Pass();
    *out_scene_hit = scene_hit.Pass();
  }
  return opaque;
}

const Resource* SceneContent::GetResource(uint32_t resource_id,
                                          Resource::Type resource_type) const {
  auto it = resources_.find(resource_id);
  DCHECK(it != resources_.end());
  DCHECK(it->second->type() == resource_type);
  return it->second.get();
}

const Node* SceneContent::GetNode(uint32_t node_id) const {
  auto it = nodes_.find(node_id);
  DCHECK(it != nodes_.end());
  return it->second.get();
}

const Node* SceneContent::GetRootNodeIfExists() const {
  auto it = nodes_.find(mojo::gfx::composition::kSceneRootNodeId);
  return it != nodes_.end() ? it->second.get() : nullptr;
}

SceneContentBuilder::SceneContentBuilder(const SceneLabel& label,
                                         uint32_t version,
                                         int64_t presentation_time,
                                         size_t max_resources,
                                         size_t max_nodes,
                                         std::ostream& err)
    : content_(new SceneContent(label,
                                version,
                                presentation_time,
                                max_resources,
                                max_nodes)),
      err_(err) {}

SceneContentBuilder::~SceneContentBuilder() {}

const Resource* SceneContentBuilder::RequireResource(
    uint32_t resource_id,
    Resource::Type resource_type,
    uint32_t referrer_node_id) {
  DCHECK(content_);

  auto it = content_->resources_.find(resource_id);
  if (it != content_->resources_.end())
    return it->second.get();

  const Resource* resource = FindResource(resource_id);
  if (!resource) {
    err_ << "Missing resource " << resource_id << " referenced from node "
         << content_->FormattedLabelForNode(referrer_node_id) << std::endl;
    return nullptr;
  }

  if (resource->type() != resource_type) {
    err_ << "Resource " << resource_id << " referenced from node "
         << content_->FormattedLabelForNode(referrer_node_id)
         << " has incorrect type for its intended usage" << std::endl;
    return nullptr;
  }

  content_->resources_.emplace(std::make_pair(resource_id, resource));
  return resource;
}

const Node* SceneContentBuilder::RequireNode(uint32_t node_id,
                                             uint32_t referrer_node_id) {
  DCHECK(content_);

  auto it = content_->nodes_.find(node_id);
  if (it != content_->nodes_.end()) {
    if (it->second)
      return it->second.get();
    err_ << "Cycle detected at node " << node_id << " referenced from node "
         << content_->FormattedLabelForNode(referrer_node_id) << std::endl;
    return nullptr;
  }

  const Node* node = FindNode(node_id);
  if (!node) {
    err_ << "Missing node " << node_id << " referenced from node "
         << content_->FormattedLabelForNode(referrer_node_id) << std::endl;
    return nullptr;
  }

  return AddNode(node) ? node : nullptr;
}

bool SceneContentBuilder::AddNode(const Node* node) {
  DCHECK(content_);
  DCHECK(node);

  // Reserve a spot in the table to mark the node recording in progress.
  DCHECK(content_->nodes_.size() < content_->nodes_.bucket_count());
  auto storage = content_->nodes_.emplace(node->node_id(), nullptr);
  DCHECK(storage.second);

  // Record the node's content.
  // This performs a depth first search of the node.  If it succeeds, we
  // will know that this part of the graph has no cycles.  Note that this
  // function may recurse back into |AddNode| to add additional nodes.
  if (!node->RecordContent(this))
    return false;

  // Store the node in the table.
  // It is safe to use the interator returned by emplace even though additional
  // nodes may have been added since the map's bucket count was initialized
  // at creation time to the total number of nodes so it should never be
  // rehashed during this traversal.
  storage.first->second = node;
  return true;
}

scoped_refptr<const SceneContent> SceneContentBuilder::Build() {
  DCHECK(content_);

  const Node* root = FindNode(mojo::gfx::composition::kSceneRootNodeId);
  return !root || AddNode(root) ? std::move(content_) : nullptr;
}

}  // namespace compositor
