// Copyright 2016 The Fuchsia 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 "src/media/playback/mediaplayer/core/conversion_pipeline_builder.h"

#include "src/media/playback/mediaplayer/graph/formatting.h"
#include "src/media/playback/mediaplayer/process/processor.h"

namespace media_player {

namespace {

// Produces a score for in_type with respect to out_type_set. The score
// is used to compare type sets to see which represents the best goal for
// conversion. Higher scores are preferred. A score of zero indicates that
// in_type is incompatible with out_type_set.
int Score(const AudioStreamType& in_type, const AudioStreamTypeSet& out_type_set) {
  // TODO(dalesat): Plenty of room for more subtlety here. Maybe actually
  // measure conversion costs (cpu, quality, etc) and reflect them here.

  int score = 0;

  if (in_type.sample_format() == out_type_set.sample_format() ||
      out_type_set.sample_format() == AudioStreamType::SampleFormat::kAny) {
    // Prefer not to convert sample format.
    score += 10;
  } else {
    // Prefer higher-quality formats.
    switch (out_type_set.sample_format()) {
      case AudioStreamType::SampleFormat::kUnsigned8:
        score += 1;
        break;
      case AudioStreamType::SampleFormat::kSigned16:
        score += 2;
        break;
      case AudioStreamType::SampleFormat::kSigned24In32:
        score += 3;
        break;
      case AudioStreamType::SampleFormat::kFloat:
        score += 4;
        break;
      default:
        FX_DCHECK(false) << "unsupported sample format " << out_type_set.sample_format();
        return 0;
    }
  }

  if (out_type_set.channels().contains(in_type.channels())) {
    // Prefer not to mixdown/up.
    score += 10;
  } else {
    return 0;  // TODO(dalesat): Remove when we have mixdown/up.
  }

  if (out_type_set.frames_per_second().contains(in_type.frames_per_second())) {
    // Very much prefer not to resample.
    score += 50;
  } else {
    return 0;  // TODO(dalesat): Remove when we have resamplers.
  }

  return score;
}

class Builder {
 public:
  Builder(const StreamType& in_type,
          const std::vector<std::unique_ptr<StreamTypeSet>>& out_type_sets, Graph* graph,
          DecoderFactory* decoder_factory, OutputRef output,
          fit::function<void(OutputRef, std::unique_ptr<StreamType>)> callback);

  void Build();

 private:
  void Succeed();

  void Fail();

  const AudioStreamTypeSet* BestLpcmOutputForInput(const AudioStreamType& audio_type);

  void AddTransformsForCompressedAudio(const AudioStreamType& audio_type);

  void AddTransformsForCompressedVideo(const VideoStreamType& video_type);

  void AddDecoder();

  void AddTransformsForLpcm(const AudioStreamType& audio_type,
                            const AudioStreamTypeSet& out_type_set);

  void AddTransformsForLpcm(const AudioStreamType& audio_type);

  std::unique_ptr<StreamType> type_;
  const std::vector<std::unique_ptr<StreamTypeSet>>& out_type_sets_;
  Graph* graph_;
  DecoderFactory* decoder_factory_;
  OutputRef output_;
  const OutputRef original_output_;
  const fit::function<void(OutputRef, std::unique_ptr<StreamType>)> callback_;
};

Builder::Builder(const StreamType& in_type,
                 const std::vector<std::unique_ptr<StreamTypeSet>>& out_type_sets, Graph* graph,
                 DecoderFactory* decoder_factory, OutputRef output,
                 fit::function<void(OutputRef, std::unique_ptr<StreamType>)> callback)
    : type_(in_type.Clone()),
      out_type_sets_(out_type_sets),
      graph_(graph),
      decoder_factory_(decoder_factory),
      output_(output),
      original_output_(output),
      callback_(std::move(callback)) {}

void Builder::Build() {
  if (type_->encrypted()) {
    // TODO(dalesat): Support encrypted types.
    FX_LOGS(ERROR) << "encrypted types not supported.";
    Fail();
    return;
  }

  switch (type_->medium()) {
    case StreamType::Medium::kAudio:
      if (type_->encoding() == StreamType::kAudioEncodingLpcm) {
        AddTransformsForLpcm(*type_->audio());
      } else {
        AddTransformsForCompressedAudio(*type_->audio());
      }
      break;
    case StreamType::Medium::kVideo:
      if (type_->encoding() == StreamType::kVideoEncodingUncompressed) {
        Succeed();
      } else {
        AddTransformsForCompressedVideo(*type_->video());
      }
      break;
    default:
      FX_LOGS(ERROR) << "conversion not supported for medium" << type_->medium();
      Fail();
      break;
  }
}

void Builder::Succeed() {
  callback_(output_, type_->Clone());
  delete this;
}

void Builder::Fail() {
  graph_->RemoveNodesConnectedToOutput(original_output_);
  callback_(original_output_, nullptr);
  delete this;
}

void Builder::AddTransformsForCompressedAudio(const AudioStreamType& audio_type) {
  // See if we have a matching audio type.
  for (const auto& out_type_set : out_type_sets_) {
    if (out_type_set->medium() == StreamType::Medium::kAudio) {
      if (out_type_set->audio()->Includes(audio_type)) {
        // No transform needed.
        type_ = audio_type.Clone();
        Succeed();
        return;
      }
      // TODO(dalesat): Support a different compressed output type by
      // transcoding.
    }
  }

  auto output = BestLpcmOutputForInput(audio_type);
  if (output == nullptr) {
    // No candidates found.
    Fail();
    return;
  }

  FX_DCHECK(output->IncludesEncoding(StreamType::kAudioEncodingLpcm));

  // Need to decode. Create a decoder and go from there.
  AddDecoder();
}

void Builder::AddTransformsForCompressedVideo(const VideoStreamType& video_type) {
  // TODO(dalesat): See if we already have a matching video type.

  AddDecoder();
}

void Builder::AddDecoder() {
  decoder_factory_->CreateDecoder(*type_, [this](std::shared_ptr<Processor> decoder) {
    if (!decoder) {
      // No decoder found.
      Fail();
      return;
    }

    output_ = graph_->ConnectOutputToNode(output_, graph_->Add(decoder)).output();
    type_ = decoder->output_stream_type();

    Build();
  });
}

// Finds the stream type set that best matches in_type.
const AudioStreamTypeSet* Builder::BestLpcmOutputForInput(const AudioStreamType& in_type) {
  StreamTypeSet* best = nullptr;
  int best_score = -1;

  for (const auto& out_type_set : out_type_sets_) {
    if (out_type_set->medium() == StreamType::Medium::kAudio &&
        out_type_set->IncludesEncoding(StreamType::kAudioEncodingLpcm)) {
      int score = Score(in_type, *out_type_set->audio());
      if (best_score < score) {
        best_score = score;
        best = out_type_set.get();
      }
    }
  }

  return best->audio();
}

void Builder::AddTransformsForLpcm(const AudioStreamType& audio_type,
                                   const AudioStreamTypeSet& out_type_set) {
  if (audio_type.sample_format() != out_type_set.sample_format() &&
      out_type_set.sample_format() != AudioStreamType::SampleFormat::kAny) {
    // TODO(dalesat): Insert sample format converter.
    FX_LOGS(ERROR) << "conversion requires sample format change - not supported";
    Fail();
    return;
  }

  if (!out_type_set.channels().contains(audio_type.channels())) {
    // TODO(dalesat): Insert mixdown/up transform.
    FX_LOGS(ERROR) << "conversion requires mixdown/up - not supported";
    Fail();
    return;
  }

  if (!out_type_set.frames_per_second().contains(audio_type.frames_per_second())) {
    // TODO(dalesat): Insert resampler.
    FX_LOGS(ERROR) << "conversion requires resampling - not supported";
    Fail();
    return;
  }

  // Build the resulting media type.
  type_ =
      AudioStreamType::Create(nullptr, StreamType::kAudioEncodingLpcm, nullptr,
                              out_type_set.sample_format() == AudioStreamType::SampleFormat::kAny
                                  ? audio_type.sample_format()
                                  : out_type_set.sample_format(),
                              audio_type.channels(), audio_type.frames_per_second());

  Succeed();
}

void Builder::AddTransformsForLpcm(const AudioStreamType& audio_type) {
  auto output = BestLpcmOutputForInput(audio_type);
  if (output == nullptr) {
    // TODO(dalesat): Support a compressed output type by encoding.
    FX_LOGS(ERROR) << "conversion using encoder not supported";
    Fail();
    return;
  }

  AddTransformsForLpcm(audio_type, *output);
}

}  // namespace

void BuildConversionPipeline(const StreamType& in_type,
                             const std::vector<std::unique_ptr<StreamTypeSet>>& out_type_sets,
                             Graph* graph, DecoderFactory* decoder_factory, OutputRef output,
                             fit::function<void(OutputRef, std::unique_ptr<StreamType>)> callback) {
  FX_DCHECK(graph);
  FX_DCHECK(decoder_factory);
  FX_DCHECK(output);
  FX_DCHECK(callback);

  auto builder =
      new Builder(in_type, out_type_sets, graph, decoder_factory, output, std::move(callback));
  builder->Build();
}

}  // namespace media_player
