/*
 *  Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include <stddef.h>
#include <stdint.h>

#include <memory>
#include <ostream>
#include <string>

#include "absl/types/optional.h"
#include "api/transport/rtp/dependency_descriptor.h"
#include "modules/video_coding/svc/create_scalability_structure.h"
#include "modules/video_coding/svc/scalability_structure_test_helpers.h"
#include "modules/video_coding/svc/scalable_video_controller.h"
#include "test/gmock.h"
#include "test/gtest.h"

namespace webrtc {
namespace {

using ::testing::AllOf;
using ::testing::Contains;
using ::testing::Each;
using ::testing::Field;
using ::testing::Ge;
using ::testing::IsEmpty;
using ::testing::Le;
using ::testing::Lt;
using ::testing::Not;
using ::testing::SizeIs;
using ::testing::TestWithParam;
using ::testing::Values;

struct SvcTestParam {
  friend std::ostream& operator<<(std::ostream& os, const SvcTestParam& param) {
    return os << param.name;
  }

  std::string name;
  int num_temporal_units;
};

class ScalabilityStructureTest : public TestWithParam<SvcTestParam> {};

TEST_P(ScalabilityStructureTest,
       NumberOfDecodeTargetsAndChainsAreInRangeAndConsistent) {
  FrameDependencyStructure structure =
      CreateScalabilityStructure(GetParam().name)->DependencyStructure();
  EXPECT_GT(structure.num_decode_targets, 0);
  EXPECT_LE(structure.num_decode_targets,
            DependencyDescriptor::kMaxDecodeTargets);
  EXPECT_GE(structure.num_chains, 0);
  EXPECT_LE(structure.num_chains, structure.num_decode_targets);
  if (structure.num_chains == 0) {
    EXPECT_THAT(structure.decode_target_protected_by_chain, IsEmpty());
  } else {
    EXPECT_THAT(structure.decode_target_protected_by_chain,
                AllOf(SizeIs(structure.num_decode_targets), Each(Ge(0)),
                      Each(Lt(structure.num_chains))));
  }
  EXPECT_THAT(structure.templates,
              SizeIs(Lt(size_t{DependencyDescriptor::kMaxTemplates})));
}

TEST_P(ScalabilityStructureTest, TemplatesAreSortedByLayerId) {
  FrameDependencyStructure structure =
      CreateScalabilityStructure(GetParam().name)->DependencyStructure();
  ASSERT_THAT(structure.templates, Not(IsEmpty()));
  const auto& first_templates = structure.templates.front();
  EXPECT_EQ(first_templates.spatial_id, 0);
  EXPECT_EQ(first_templates.temporal_id, 0);
  for (size_t i = 1; i < structure.templates.size(); ++i) {
    const auto& prev_template = structure.templates[i - 1];
    const auto& next_template = structure.templates[i];
    if (next_template.spatial_id == prev_template.spatial_id &&
        next_template.temporal_id == prev_template.temporal_id) {
      // Same layer, next_layer_idc == 0
    } else if (next_template.spatial_id == prev_template.spatial_id &&
               next_template.temporal_id == prev_template.temporal_id + 1) {
      // Next temporal layer, next_layer_idc == 1
    } else if (next_template.spatial_id == prev_template.spatial_id + 1 &&
               next_template.temporal_id == 0) {
      // Next spatial layer, next_layer_idc == 2
    } else {
      // everything else is invalid.
      ADD_FAILURE() << "Invalid templates order. Template #" << i
                    << " with layer (" << next_template.spatial_id << ","
                    << next_template.temporal_id
                    << ") follows template with layer ("
                    << prev_template.spatial_id << ","
                    << prev_template.temporal_id << ").";
    }
  }
}

TEST_P(ScalabilityStructureTest, TemplatesMatchNumberOfDecodeTargetsAndChains) {
  FrameDependencyStructure structure =
      CreateScalabilityStructure(GetParam().name)->DependencyStructure();
  EXPECT_THAT(
      structure.templates,
      Each(AllOf(Field(&FrameDependencyTemplate::decode_target_indications,
                       SizeIs(structure.num_decode_targets)),
                 Field(&FrameDependencyTemplate::chain_diffs,
                       SizeIs(structure.num_chains)))));
}

TEST_P(ScalabilityStructureTest, FrameInfoMatchesFrameDependencyStructure) {
  std::unique_ptr<ScalableVideoController> svc_controller =
      CreateScalabilityStructure(GetParam().name);
  FrameDependencyStructure structure = svc_controller->DependencyStructure();
  std::vector<GenericFrameInfo> frame_infos =
      ScalabilityStructureWrapper(*svc_controller)
          .GenerateFrames(GetParam().num_temporal_units);
  for (size_t frame_id = 0; frame_id < frame_infos.size(); ++frame_id) {
    const auto& frame = frame_infos[frame_id];
    EXPECT_GE(frame.spatial_id, 0) << " for frame " << frame_id;
    EXPECT_GE(frame.temporal_id, 0) << " for frame " << frame_id;
    EXPECT_THAT(frame.decode_target_indications,
                SizeIs(structure.num_decode_targets))
        << " for frame " << frame_id;
    EXPECT_THAT(frame.part_of_chain, SizeIs(structure.num_chains))
        << " for frame " << frame_id;
  }
}

TEST_P(ScalabilityStructureTest, ThereIsAPerfectTemplateForEachFrame) {
  std::unique_ptr<ScalableVideoController> svc_controller =
      CreateScalabilityStructure(GetParam().name);
  FrameDependencyStructure structure = svc_controller->DependencyStructure();
  std::vector<GenericFrameInfo> frame_infos =
      ScalabilityStructureWrapper(*svc_controller)
          .GenerateFrames(GetParam().num_temporal_units);
  for (size_t frame_id = 0; frame_id < frame_infos.size(); ++frame_id) {
    EXPECT_THAT(structure.templates, Contains(frame_infos[frame_id]))
        << " for frame " << frame_id;
  }
}

TEST_P(ScalabilityStructureTest, FrameDependsOnSameOrLowerLayer) {
  std::unique_ptr<ScalableVideoController> svc_controller =
      CreateScalabilityStructure(GetParam().name);
  std::vector<GenericFrameInfo> frame_infos =
      ScalabilityStructureWrapper(*svc_controller)
          .GenerateFrames(GetParam().num_temporal_units);
  int64_t num_frames = frame_infos.size();

  for (int64_t frame_id = 0; frame_id < num_frames; ++frame_id) {
    const auto& frame = frame_infos[frame_id];
    for (int frame_diff : frame.frame_diffs) {
      int64_t base_frame_id = frame_id - frame_diff;
      const auto& base_frame = frame_infos[base_frame_id];
      EXPECT_GE(frame.spatial_id, base_frame.spatial_id)
          << "Frame " << frame_id << " depends on frame " << base_frame_id;
      EXPECT_GE(frame.temporal_id, base_frame.temporal_id)
          << "Frame " << frame_id << " depends on frame " << base_frame_id;
    }
  }
}

TEST_P(ScalabilityStructureTest, NoFrameDependsOnDiscardableOrNotPresent) {
  std::unique_ptr<ScalableVideoController> svc_controller =
      CreateScalabilityStructure(GetParam().name);
  std::vector<GenericFrameInfo> frame_infos =
      ScalabilityStructureWrapper(*svc_controller)
          .GenerateFrames(GetParam().num_temporal_units);
  int64_t num_frames = frame_infos.size();
  FrameDependencyStructure structure = svc_controller->DependencyStructure();

  for (int dt = 0; dt < structure.num_decode_targets; ++dt) {
    for (int64_t frame_id = 0; frame_id < num_frames; ++frame_id) {
      const auto& frame = frame_infos[frame_id];
      if (frame.decode_target_indications[dt] ==
          DecodeTargetIndication::kNotPresent) {
        continue;
      }
      for (int frame_diff : frame.frame_diffs) {
        int64_t base_frame_id = frame_id - frame_diff;
        const auto& base_frame = frame_infos[base_frame_id];
        EXPECT_NE(base_frame.decode_target_indications[dt],
                  DecodeTargetIndication::kNotPresent)
            << "Frame " << frame_id << " depends on frame " << base_frame_id
            << " that is not part of decode target#" << dt;
        EXPECT_NE(base_frame.decode_target_indications[dt],
                  DecodeTargetIndication::kDiscardable)
            << "Frame " << frame_id << " depends on frame " << base_frame_id
            << " that is discardable for decode target#" << dt;
      }
    }
  }
}

TEST_P(ScalabilityStructureTest, NoFrameDependsThroughSwitchIndication) {
  std::unique_ptr<ScalableVideoController> svc_controller =
      CreateScalabilityStructure(GetParam().name);
  FrameDependencyStructure structure = svc_controller->DependencyStructure();
  std::vector<GenericFrameInfo> frame_infos =
      ScalabilityStructureWrapper(*svc_controller)
          .GenerateFrames(GetParam().num_temporal_units);
  int64_t num_frames = frame_infos.size();
  std::vector<std::set<int64_t>> full_deps(num_frames);

  // For each frame calculate set of all frames it depends on, both directly and
  // indirectly.
  for (int64_t frame_id = 0; frame_id < num_frames; ++frame_id) {
    std::set<int64_t> all_base_frames;
    for (int frame_diff : frame_infos[frame_id].frame_diffs) {
      int64_t base_frame_id = frame_id - frame_diff;
      all_base_frames.insert(base_frame_id);
      const auto& indirect = full_deps[base_frame_id];
      all_base_frames.insert(indirect.begin(), indirect.end());
    }
    full_deps[frame_id] = std::move(all_base_frames);
  }

  // Now check the switch indication: frames after the switch indication mustn't
  // depend on any addition frames before the switch indications.
  for (int dt = 0; dt < structure.num_decode_targets; ++dt) {
    for (int64_t switch_frame_id = 0; switch_frame_id < num_frames;
         ++switch_frame_id) {
      if (frame_infos[switch_frame_id].decode_target_indications[dt] !=
          DecodeTargetIndication::kSwitch) {
        continue;
      }
      for (int64_t later_frame_id = switch_frame_id + 1;
           later_frame_id < num_frames; ++later_frame_id) {
        if (frame_infos[later_frame_id].decode_target_indications[dt] ==
            DecodeTargetIndication::kNotPresent) {
          continue;
        }
        for (int frame_diff : frame_infos[later_frame_id].frame_diffs) {
          int64_t early_frame_id = later_frame_id - frame_diff;
          if (early_frame_id < switch_frame_id) {
            EXPECT_THAT(full_deps[switch_frame_id], Contains(early_frame_id))
                << "For decode target #" << dt << " frame " << later_frame_id
                << " depends on the frame " << early_frame_id
                << " that switch indication frame " << switch_frame_id
                << " doesn't directly on indirectly depend on.";
          }
        }
      }
    }
  }
}

TEST_P(ScalabilityStructureTest, ProduceNoFrameForDisabledLayers) {
  std::unique_ptr<ScalableVideoController> svc_controller =
      CreateScalabilityStructure(GetParam().name);
  ScalableVideoController::StreamLayersConfig structure =
      svc_controller->StreamConfig();

  VideoBitrateAllocation all_bitrates;
  for (int sid = 0; sid < structure.num_spatial_layers; ++sid) {
    for (int tid = 0; tid < structure.num_temporal_layers; ++tid) {
      all_bitrates.SetBitrate(sid, tid, 100'000);
    }
  }

  svc_controller->OnRatesUpdated(all_bitrates);
  ScalabilityStructureWrapper wrapper(*svc_controller);
  std::vector<GenericFrameInfo> frames =
      wrapper.GenerateFrames(GetParam().num_temporal_units);

  for (int sid = 0; sid < structure.num_spatial_layers; ++sid) {
    for (int tid = 0; tid < structure.num_temporal_layers; ++tid) {
      // When all layers were enabled, expect there was a frame for each layer.
      EXPECT_THAT(frames,
                  Contains(AllOf(Field(&GenericFrameInfo::spatial_id, sid),
                                 Field(&GenericFrameInfo::temporal_id, tid))))
          << "For layer (" << sid << "," << tid << ")";
      // Restore bitrates for all layers before disabling single layer.
      VideoBitrateAllocation bitrates = all_bitrates;
      bitrates.SetBitrate(sid, tid, 0);
      svc_controller->OnRatesUpdated(bitrates);
      // With layer (sid, tid) disabled, expect no frames are produced for it.
      EXPECT_THAT(
          wrapper.GenerateFrames(GetParam().num_temporal_units),
          Not(Contains(AllOf(Field(&GenericFrameInfo::spatial_id, sid),
                             Field(&GenericFrameInfo::temporal_id, tid)))))
          << "For layer (" << sid << "," << tid << ")";
    }
  }
}

INSTANTIATE_TEST_SUITE_P(
    Svc,
    ScalabilityStructureTest,
    Values(SvcTestParam{"L1T2", /*num_temporal_units=*/4},
           SvcTestParam{"L1T3", /*num_temporal_units=*/8},
           SvcTestParam{"L2T1", /*num_temporal_units=*/3},
           SvcTestParam{"L2T1_KEY", /*num_temporal_units=*/3},
           SvcTestParam{"L3T1", /*num_temporal_units=*/3},
           SvcTestParam{"L3T3", /*num_temporal_units=*/8},
           SvcTestParam{"S2T1", /*num_temporal_units=*/3},
           SvcTestParam{"L2T2", /*num_temporal_units=*/4},
           SvcTestParam{"L2T2_KEY", /*num_temporal_units=*/4},
           SvcTestParam{"L2T2_KEY_SHIFT", /*num_temporal_units=*/4},
           SvcTestParam{"L3T3_KEY", /*num_temporal_units=*/8}),
    [](const testing::TestParamInfo<SvcTestParam>& info) {
      return info.param.name;
    });

}  // namespace
}  // namespace webrtc
