// Copyright 2013 The Flutter 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 "impeller/entity/entity_pass_clip_stack.h"
#include "impeller/entity/contents/clip_contents.h"
#include "impeller/entity/contents/content_context.h"
#include "impeller/entity/entity.h"

namespace impeller {

EntityPassClipStack::EntityPassClipStack(const Rect& initial_coverage_rect) {
  subpass_state_.push_back(SubpassState{
      .clip_coverage =
          {
              {ClipCoverageLayer{
                  .coverage = initial_coverage_rect,
                  .clip_height = 0,
              }},
          },
  });
}

std::optional<Rect> EntityPassClipStack::CurrentClipCoverage() const {
  return subpass_state_.back().clip_coverage.back().coverage;
}

bool EntityPassClipStack::HasCoverage() const {
  return !subpass_state_.back().clip_coverage.empty();
}

void EntityPassClipStack::PushSubpass(std::optional<Rect> subpass_coverage,
                                      size_t clip_height) {
  subpass_state_.push_back(SubpassState{
      .clip_coverage =
          {
              ClipCoverageLayer{.coverage = subpass_coverage,
                                .clip_height = clip_height},
          },
  });
}

void EntityPassClipStack::PopSubpass() {
  subpass_state_.pop_back();
}

const std::vector<ClipCoverageLayer>
EntityPassClipStack::GetClipCoverageLayers() const {
  return subpass_state_.back().clip_coverage;
}

EntityPassClipStack::ClipStateResult EntityPassClipStack::ApplyClipState(
    Contents::ClipCoverage global_clip_coverage,
    Entity& entity,
    size_t clip_height_floor,
    Point global_pass_position) {
  ClipStateResult result = {.should_render = false, .clip_did_change = false};

  auto& subpass_state = GetCurrentSubpassState();
  switch (global_clip_coverage.type) {
    case Contents::ClipCoverage::Type::kNoChange:
      break;
    case Contents::ClipCoverage::Type::kAppend: {
      auto op = CurrentClipCoverage();

      // Compute the previous clip height.
      size_t previous_clip_height = 0;
      if (!subpass_state.clip_coverage.empty()) {
        previous_clip_height = subpass_state.clip_coverage.back().clip_height;
      } else {
        // If there is no clip coverage, then the previous clip height is the
        // clip height floor.
        previous_clip_height = clip_height_floor;
      }

      subpass_state.clip_coverage.push_back(
          ClipCoverageLayer{.coverage = global_clip_coverage.coverage,
                            .clip_height = previous_clip_height + 1});
      result.clip_did_change = true;

      FML_DCHECK(subpass_state.clip_coverage.back().clip_height ==
                 subpass_state.clip_coverage.front().clip_height +
                     subpass_state.clip_coverage.size() - 1);

      if (!op.has_value()) {
        // Running this append op won't impact the clip buffer because the
        // whole screen is already being clipped, so skip it.
        return result;
      }
    } break;
    case Contents::ClipCoverage::Type::kRestore: {
      ClipRestoreContents* restore_contents =
          reinterpret_cast<ClipRestoreContents*>(entity.GetContents().get());
      size_t restore_height = restore_contents->GetRestoreHeight();

      if (subpass_state.clip_coverage.back().clip_height <= restore_height) {
        // Drop clip restores that will do nothing.
        return result;
      }

      auto restoration_index =
          restore_height - subpass_state.clip_coverage.front().clip_height;
      FML_DCHECK(restoration_index < subpass_state.clip_coverage.size());

      // We only need to restore the area that covers the coverage of the
      // clip rect at target depth + 1.
      std::optional<Rect> restore_coverage =
          (restoration_index + 1 < subpass_state.clip_coverage.size())
              ? subpass_state.clip_coverage[restoration_index + 1].coverage
              : std::nullopt;
      if (restore_coverage.has_value()) {
        // Make the coverage rectangle relative to the current pass.
        restore_coverage = restore_coverage->Shift(-global_pass_position);
      }
      subpass_state.clip_coverage.resize(restoration_index + 1);
      result.clip_did_change = true;

      // Skip all clip restores when stencil-then-cover is enabled.
      if (subpass_state.clip_coverage.back().coverage.has_value()) {
        RecordEntity(entity, global_clip_coverage.type, Rect());
      }
      return result;

    } break;
  }

#ifdef IMPELLER_ENABLE_CAPTURE
  {
    auto element_entity_coverage = entity.GetCoverage();
    if (element_entity_coverage.has_value()) {
      element_entity_coverage =
          element_entity_coverage->Shift(global_pass_position);
      entity.GetCapture().AddRect("Coverage", *element_entity_coverage,
                                  {.readonly = true});
    }
  }
#endif

  RecordEntity(entity, global_clip_coverage.type,
               subpass_state.clip_coverage.back().coverage);

  result.should_render = true;
  return result;
}

void EntityPassClipStack::RecordEntity(const Entity& entity,
                                       Contents::ClipCoverage::Type type,
                                       std::optional<Rect> clip_coverage) {
  auto& subpass_state = GetCurrentSubpassState();
  switch (type) {
    case Contents::ClipCoverage::Type::kNoChange:
      return;
    case Contents::ClipCoverage::Type::kAppend:
      subpass_state.rendered_clip_entities.push_back(
          {.entity = entity.Clone(), .clip_coverage = clip_coverage});
      break;
    case Contents::ClipCoverage::Type::kRestore:
      if (!subpass_state.rendered_clip_entities.empty()) {
        subpass_state.rendered_clip_entities.pop_back();
      }
      break;
  }
}

EntityPassClipStack::SubpassState&
EntityPassClipStack::GetCurrentSubpassState() {
  return subpass_state_.back();
}

const std::vector<EntityPassClipStack::ReplayResult>&
EntityPassClipStack::GetReplayEntities() const {
  return subpass_state_.back().rendered_clip_entities;
}

}  // namespace impeller
