// Copyright 2018 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/core/layout/ng/ng_flex_layout_algorithm.h"

#include <memory>
#include "third_party/blink/renderer/core/layout/flexible_box_algorithm.h"
#include "third_party/blink/renderer/core/layout/layout_box.h"
#include "third_party/blink/renderer/core/layout/layout_flexible_box.h"
#include "third_party/blink/renderer/core/layout/ng/ng_block_break_token.h"
#include "third_party/blink/renderer/core/layout/ng/ng_constraint_space.h"
#include "third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h"
#include "third_party/blink/renderer/core/layout/ng/ng_length_utils.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"

namespace blink {

NGFlexLayoutAlgorithm::NGFlexLayoutAlgorithm(NGBlockNode node,
                                             const NGConstraintSpace& space,
                                             const NGBreakToken* break_token)
    : NGLayoutAlgorithm(node, space, ToNGBlockBreakToken(break_token)) {}

scoped_refptr<NGLayoutResult> NGFlexLayoutAlgorithm::Layout() {
  DCHECK(!Style().IsColumnFlexDirection())
      << "Column flexboxes aren't supported yet";
  DCHECK(!NeedMinMaxSize(ConstraintSpace(), Style()))
      << "Don't support that yet";

  NGLogicalSize flex_container_border_box_size =
      CalculateBorderBoxSize(ConstraintSpace(), Node());
  NGBoxStrut flex_container_border_scrollbar_padding =
      CalculateBorderScrollbarPadding(ConstraintSpace(), Node());
  NGLogicalSize flex_container_content_box_size = ShrinkAvailableSize(
      flex_container_border_box_size, flex_container_border_scrollbar_padding);
  LayoutUnit flex_container_border_box_inline_size =
      flex_container_border_box_size.inline_size;
  LayoutUnit flex_container_content_inline_size =
      flex_container_content_box_size.inline_size;

  FlexLayoutAlgorithm algorithm(&Style(), flex_container_content_inline_size);
  for (NGLayoutInputNode generic_child = Node().FirstChild(); generic_child;
       generic_child = generic_child.NextSibling()) {
    NGBlockNode child = ToNGBlockNode(generic_child);
    if (child.IsOutOfFlowPositioned())
      continue;

    NGConstraintSpace child_space =
        NGConstraintSpaceBuilder(ConstraintSpace())
            .SetAvailableSize(flex_container_content_box_size)
            .SetPercentageResolutionSize(flex_container_content_box_size)
            .ToConstraintSpace(child.Style().GetWritingMode());

    LayoutUnit main_axis_border_and_padding =
        ComputeBorders(child_space, child.Style()).InlineSum() +
        ComputePadding(child_space, child.Style()).InlineSum();
    // ComputeMinMaxSize will layout the child if it has an orthogonal writing
    // mode. MinMaxSize will be in the container's inline direction.
    MinMaxSizeInput zero_input;
    MinMaxSize min_max_sizes_border_box = child.ComputeMinMaxSize(
        ConstraintSpace().GetWritingMode(), zero_input, &child_space);

    LayoutUnit flex_base_border_box;
    if (child.Style().FlexBasis().IsAuto() && child.Style().Width().IsAuto()) {
      flex_base_border_box = min_max_sizes_border_box.max_size;
    } else {
      Length length_to_resolve = child.Style().FlexBasis();
      if (length_to_resolve.IsAuto())
        length_to_resolve = child.Style().Width();
      DCHECK(!length_to_resolve.IsAuto());

      // TODO(dgrogan): Use ResolveBlockLength here for column flex boxes.

      flex_base_border_box = ResolveInlineLength(
          child_space, child.Style(), min_max_sizes_border_box,
          length_to_resolve, LengthResolveType::kContentSize,
          LengthResolvePhase::kLayout);
    }

    // Spec calls this "flex base size"
    // https://www.w3.org/TR/css-flexbox-1/#algo-main-item
    // Blink's FlexibleBoxAlgorithm expects it to be content + scrollbar widths,
    // but no padding or border.
    LayoutUnit flex_base_content_size =
        flex_base_border_box - main_axis_border_and_padding;

    LayoutUnit main_axis_margin =
        ComputeMarginsForSelf(child_space, child.Style()).InlineSum();

    // TODO(dgrogan): When child has a min/max-{width,height} set, call
    // Resolve{Inline,Block}Length here with child's style and constraint space.
    // Pass kMinSize, kMaxSize as appropriate.
    // Further, min-width:auto has special meaning for flex items. We'll need to
    // calculate that here by either extracting the logic from legacy or
    // reimplementing. When resolved, pass it here.
    // https://www.w3.org/TR/css-flexbox-1/#min-size-auto
    MinMaxSize min_max_sizes_in_main_axis_direction{LayoutUnit(),
                                                    LayoutUnit::Max()};
    algorithm
        .emplace_back(child.GetLayoutBox(), flex_base_content_size,
                      min_max_sizes_in_main_axis_direction,
                      main_axis_border_and_padding, main_axis_margin)
        .ng_input_node = child;
  }

  LayoutUnit main_axis_offset =
      flex_container_border_scrollbar_padding.inline_start;
  LayoutUnit cross_axis_offset =
      flex_container_border_scrollbar_padding.block_start;
  FlexLine* line;
  while ((line = algorithm.ComputeNextFlexLine(
              flex_container_border_box_inline_size))) {
    // TODO(dgrogan): This parameter is more complicated for columns.
    line->SetContainerMainInnerSize(flex_container_content_inline_size);
    line->FreezeInflexibleItems();
    while (!line->ResolveFlexibleLengths()) {
      continue;
    }
    for (wtf_size_t i = 0; i < line->line_items.size(); ++i) {
      FlexItem& flex_item = line->line_items[i];
      NGConstraintSpaceBuilder space_builder(ConstraintSpace());
      NGLogicalSize available_size(flex_item.flexed_content_size +
                                       flex_item.main_axis_border_and_padding,
                                   flex_container_content_box_size.block_size);
      space_builder.SetAvailableSize(available_size);
      space_builder.SetPercentageResolutionSize(
          flex_container_content_box_size);
      space_builder.SetIsFixedSizeInline(true);
      NGConstraintSpace child_space = space_builder.ToConstraintSpace(
          flex_item.box->Style()->GetWritingMode());
      flex_item.layout_result =
          ToNGBlockNode(flex_item.ng_input_node)
              .Layout(child_space, nullptr /*break token*/);
      flex_item.cross_axis_size =
          flex_item.layout_result->PhysicalFragment()->Size().height;
      // TODO(dgrogan): Port logic from
      // LayoutFlexibleBox::CrossAxisIntrinsicExtentForChild?
      flex_item.cross_axis_intrinsic_size = flex_item.cross_axis_size;
    }
    // cross_axis_offset is updated in each iteration of the loop, for passing
    // in to the next iteration.
    line->ComputeLineItemsPosition(main_axis_offset, cross_axis_offset);


    // TODO(dgrogan): For column flex containers, keep track of tallest flex
    // line and pass to ComputeBlockSizeForFragment as content_size.
  }
  LayoutUnit intrinsic_block_content_size = cross_axis_offset;
  LayoutUnit intrinsic_block_size =
      intrinsic_block_content_size +
      flex_container_border_scrollbar_padding.BlockSum();
  LayoutUnit block_size = ComputeBlockSizeForFragment(
      ConstraintSpace(), Style(), intrinsic_block_size);

  // Apply stretch alignment.
  // TODO(dgrogan): Move this to its own method, which means making some of the
  // container-specific local variables into data members.
  // TODO(dgrogan): Change this to final_content_cross_size when column
  // flexboxes are supported.
  LayoutUnit final_content_block_size =
      block_size - flex_container_border_scrollbar_padding.BlockSum();
  for (FlexLine& line_context : algorithm.FlexLines()) {
    for (wtf_size_t child_number = 0;
         child_number < line_context.line_items.size(); ++child_number) {
      FlexItem& flex_item = line_context.line_items[child_number];
      if (flex_item.Alignment() == ItemPosition::kStretch) {
        flex_item.ComputeStretchedSize(
            // TODO(dgrogan): Change this to line_context.cross_axis_extent once
            // lines are also sized and spaced.
            final_content_block_size);
        NGConstraintSpaceBuilder space_builder(ConstraintSpace());
        NGLogicalSize available_size(flex_item.flexed_content_size +
                                         flex_item.main_axis_border_and_padding,
                                     flex_item.cross_axis_size);
        space_builder.SetAvailableSize(available_size);
        space_builder.SetPercentageResolutionSize(
            flex_container_content_box_size);
        space_builder.SetIsFixedSizeInline(true);
        space_builder.SetIsFixedSizeBlock(true);
        NGConstraintSpace child_space = space_builder.ToConstraintSpace(
            flex_item.box->Style()->GetWritingMode());
        flex_item.layout_result =
            ToNGBlockNode(flex_item.ng_input_node)
                .Layout(child_space, nullptr /*break token*/);
      }
      container_builder_.AddChild(
          *flex_item.layout_result,
          {flex_item.desired_location.X(), flex_item.desired_location.Y()});
    }
  }

  container_builder_.SetBlockSize(block_size);
  container_builder_.SetInlineSize(flex_container_border_box_inline_size);
  container_builder_.SetBorders(ComputeBorders(ConstraintSpace(), Style()));
  container_builder_.SetPadding(ComputePadding(ConstraintSpace(), Style()));
  return container_builder_.ToBoxFragment();
}

base::Optional<MinMaxSize> NGFlexLayoutAlgorithm::ComputeMinMaxSize(
    const MinMaxSizeInput& input) const {
  // TODO(dgrogan): Implement this.
  return base::nullopt;
}

}  // namespace blink
