// Copyright 2020 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 "third_party/blink/renderer/modules/xr/xr_plane_manager.h"

#include "base/trace_event/trace_event.h"
#include "third_party/blink/renderer/modules/xr/xr_plane.h"
#include "third_party/blink/renderer/modules/xr/xr_plane_set.h"

namespace blink {

XRPlaneManager::XRPlaneManager(base::PassKey<XRSession> pass_key,
                               XRSession* session)
    : session_(session) {}

void XRPlaneManager::ProcessPlaneInformation(
    const device::mojom::blink::XRPlaneDetectionData* detected_planes_data,
    double timestamp) {
  TRACE_EVENT0("xr", __FUNCTION__);

  if (!detected_planes_data) {
    DVLOG(3) << __func__ << ": detected_planes_data is null";

    // We have received a nullopt - plane detection is not supported or
    // disabled. Mark detected_planes as null & clear stored planes.
    is_detected_planes_null_ = true;
    plane_ids_to_planes_.clear();
    return;
  }

  TRACE_COUNTER2("xr", "Plane statistics", "All planes",
                 detected_planes_data->all_planes_ids.size(), "Updated planes",
                 detected_planes_data->updated_planes_data.size());

  DVLOG(3) << __func__ << ": updated planes size="
           << detected_planes_data->updated_planes_data.size()
           << ", all planes size="
           << detected_planes_data->all_planes_ids.size();

  is_detected_planes_null_ = false;

  HeapHashMap<uint64_t, Member<XRPlane>> updated_planes;

  // First, process all planes that had their information updated (new planes
  // are also processed here).
  for (const auto& plane : detected_planes_data->updated_planes_data) {
    DCHECK(plane);

    auto it = plane_ids_to_planes_.find(plane->id);
    if (it != plane_ids_to_planes_.end()) {
      updated_planes.insert(plane->id, it->value);
      it->value->Update(*plane, timestamp);
    } else {
      updated_planes.insert(
          plane->id, MakeGarbageCollected<XRPlane>(plane->id, session_, *plane,
                                                   timestamp));
    }
  }

  // Then, copy over the planes that were not updated but are still present.
  for (const auto& plane_id : detected_planes_data->all_planes_ids) {
    // If the plane was already updated, there is nothing to do as it was
    // already moved to |updated_planes|. If it's not updated, just copy it over
    // as-is.
    if (!base::Contains(updated_planes, plane_id)) {
      auto it = plane_ids_to_planes_.find(plane_id);
      DCHECK(it != plane_ids_to_planes_.end());
      updated_planes.insert(plane_id, it->value);
    }
  }

  plane_ids_to_planes_.swap(updated_planes);
}

XRPlaneSet* XRPlaneManager::GetDetectedPlanes() const {
  if (is_detected_planes_null_)
    return nullptr;

  HeapHashSet<Member<XRPlane>> result;
  for (auto& plane_id_and_plane : plane_ids_to_planes_) {
    result.insert(plane_id_and_plane.value);
  }

  return MakeGarbageCollected<XRPlaneSet>(result);
}

void XRPlaneManager::Trace(Visitor* visitor) const {
  visitor->Trace(session_);
  visitor->Trace(plane_ids_to_planes_);
}

}  // namespace blink
