require "rails_helper"

RSpec.describe EdlEventGateway do
  let(:files_for_request) do
    instance_double(FilesForRequest,
      file_object_name: "file_object_name",
      edl_file_object_name: "edl_file_object_name",
      aws_bucket_name: "aws_bucket_name",
      start_timecode_offset: nil,
      job_id: "video_analysis_uid",
    )
  end

  describe "#edl_events" do
    it "filters edl events by channel_filter" do
      video_event = BrayniacAI::EdlParseResult.new({
        "channel" => "V",
        "start_time" => 0,
        "timecode_in" => "00:00:00:00",
        "timecode_out" => "00:00:01:00",
        "duration" => 1,
        "source_file_name" => "my_file.mp4",
        "clip_name" => "my_clip.mp4",
        "description" => "This is a great clip",
        "matches" => [1, 2],
      })
      audio_event = BrayniacAI::EdlParseResult.new({
        "channel" => "A1",
        "start_time" => 0,
        "timecode_in" => "00:00:00:00",
        "timecode_out" => "00:00:01:00",
        "duration" => 1,
        "source_file_name" => "my_file.mp3",
        "clip_name" => "my_clip.mp3",
        "description" => "This is a great clip",
        "matches" => [1, 2],
      })

      allow(BrayniacAI::EdlParse).to receive(:create).and_return(
        BrayniacAI::EdlParse.new({ results: [video_event, audio_event] })
      )

      edl_events = EdlEventGateway.new(
        files_for_request,
        "00:00:02:00",
        "00:00:02:00",
        channel_filter: "A",
      ).edl_events

      expect(edl_events.size).to eq(1)
      expect(edl_events).to include(EdlEvent.new({
        "channel" => "A1",
        "start_time" => 0,
        "timecode_in" => "00:00:00:00",
        "timecode_out" => "00:00:01:00",
        "duration" => 1,
        "source_file_name" => "my_file.mp3",
        "clip_name" => "my_clip.mp3",
        "description" => "This is a great clip",
        "matches" => [1, 2],
      }))
    end

    describe "calling the API" do
      it "includes location information about the video file and EDL file" do
        allow(ENV).to receive(:[]).with("AWS_BUCKET").and_return("test-bucket")
        allow(BrayniacAI::EdlParse).to receive(:create)

        EdlEventGateway.new(
          files_for_request,
          "00:00:02:00",
          "00:00:02:00",
        ).edl_events

        expect(BrayniacAI::EdlParse).to have_received(:create).with(
          job_id: "video_analysis_uid",
          video_bucket_name: "aws_bucket_name",
          video_object_name: "file_object_name",
          edl_bucket_name: "aws_bucket_name",
          edl_object_name: "edl_file_object_name",
          timecode_start: "00:00:02:00",
          timecode_end: "00:00:02:00",
          collection: {},
        )
      end

      it "includes collection when provided" do
        allow(ENV).to receive(:[]).with("AWS_BUCKET").and_return("test-bucket")
        allow(BrayniacAI::EdlParse).to receive(:create)

        EdlEventGateway.new(
          files_for_request,
          "00:00:02:00",
          "00:00:02:00",
          collection: { 1 => "source file name" },
        ).edl_events

        expect(BrayniacAI::EdlParse).to have_received(:create).with(
          job_id: "video_analysis_uid",
          video_bucket_name: "aws_bucket_name",
          video_object_name: "file_object_name",
          edl_bucket_name: "aws_bucket_name",
          edl_object_name: "edl_file_object_name",
          timecode_start: "00:00:02:00",
          timecode_end: "00:00:02:00",
          collection: { 1 => "source file name" },
        )
      end

      it "includes start_timecode_offset when provided" do
        allow(files_for_request).to receive(:start_timecode_offset).and_return("start_timecode_offset")
        allow(BrayniacAI::EdlParse).to receive(:create)

        EdlEventGateway.new(
          files_for_request,
          "00:00:02:00",
          "00:00:02:00",
        ).edl_events

        expect(BrayniacAI::EdlParse).to have_received(:create).with(
          job_id: "video_analysis_uid",
          video_bucket_name: "aws_bucket_name",
          video_object_name: "file_object_name",
          edl_bucket_name: "aws_bucket_name",
          edl_object_name: "edl_file_object_name",
          timecode_start: "00:00:02:00",
          timecode_end: "00:00:02:00",
          collection: {},
          edl_timecode_start: "start_timecode_offset",
        )
      end

      it "does not include timecode_end, edl_timecode_start, job_id when given nil" do
        allow(ENV).to receive(:[]).with("AWS_BUCKET").and_return("test-bucket")
        allow(BrayniacAI::EdlParse).to receive(:create)
        allow(files_for_request).to receive(:job_id).and_return(nil)

        EdlEventGateway.new(
          files_for_request,
          "00:00:02:00",
          nil,
          collection: { 1 => "source file name" },
        ).edl_events

        expect(BrayniacAI::EdlParse).to have_received(:create).with(
          video_bucket_name: "aws_bucket_name",
          video_object_name: "file_object_name",
          edl_bucket_name: "aws_bucket_name",
          edl_object_name: "edl_file_object_name",
          timecode_start: "00:00:02:00",
          collection: { 1 => "source file name" },
        )
      end
    end

    it "returns the collection of edl events from response" do
      edl_event = BrayniacAI::EdlParseResult.new({
        "channel" => "V",
        "start_time" => 0,
        "timecode_in" => "00:00:00:00",
        "timecode_out" => "00:00:01:00",
        "duration" => 1,
        "source_file_name" => "my_file.mp4",
        "clip_name" => "my_clip.mp4",
        "description" => "This is a great clip",
        "matches" => [1, 2],
      })

      allow(BrayniacAI::EdlParse).to receive(:create).and_return(
        BrayniacAI::EdlParse.new({ results: [edl_event] })
      )

      edl_events = EdlEventGateway.new(
        files_for_request,
        "00:00:02:00",
        "00:00:02:00",
      ).edl_events

      expect(edl_events.size).to eq(1)
      expect(edl_events).to include(EdlEvent.new({
        "channel" => "V",
        "start_time" => 0,
        "timecode_in" => "00:00:00:00",
        "timecode_out" => "00:00:01:00",
        "duration" => 1,
        "source_file_name" => "my_file.mp4",
        "clip_name" => "my_clip.mp4",
        "description" => "This is a great clip",
        "matches" => [1, 2],
      }))
    end
  end

  describe "#edl_timecode_start" do
    it "returns edl_timecode_start from response" do
      allow(BrayniacAI::EdlParse).to receive(:create).and_return(BrayniacAI::EdlParse.new(edl_timecode_start: "edl_timecode_start"))

      expect(described_class.new(
        files_for_request,
        "00:00:00:00",
        "00:00:00:00"
      ).edl_timecode_start).to eq "edl_timecode_start"
    end

    context "when response nil" do
      it "returns edl_timecode_start from response" do
        allow(BrayniacAI::EdlParse).to receive(:create).and_return(nil)

        expect(described_class.new(
          files_for_request,
          "00:00:00:00",
          "00:00:00:00"
        ).edl_timecode_start).to be_nil
      end
    end
  end

  describe "#fps" do
    it "returns fps from response" do
      allow(BrayniacAI::EdlParse).to receive(:create).and_return(BrayniacAI::EdlParse.new(fps: 29.97))

      expect(described_class.new(
        files_for_request,
        "00:00:00:00",
        "00:00:00:00"
      ).fps).to eq 29.97
    end

    context "when response nil" do
      it "returns nil" do
        allow(BrayniacAI::EdlParse).to receive(:create).and_return(nil)

        expect(described_class.new(
          files_for_request,
          "00:00:00:00",
          "00:00:00:00"
        ).fps).to be_nil
      end
    end
  end

  describe "#edl_offset_seconds" do
    it "returns edl_offset_seconds from response" do
      allow(BrayniacAI::EdlParse).to receive(:create).and_return(BrayniacAI::EdlParse.new(edl_offset_seconds: 100))

      expect(described_class.new(
        files_for_request,
        "00:00:00:00",
        "00:00:00:00"
      ).edl_offset_seconds).to eq 100 
    end

    context "when response nil" do
      it "returns edl_offset_seconds from response" do
        allow(BrayniacAI::EdlParse).to receive(:create).and_return(nil)

        expect(described_class.new(
          files_for_request,
          "00:00:00:00",
          "00:00:00:00"
        ).edl_offset_seconds).to be_nil
      end
    end
  end
end
