#!/usr/bin/ruby
# frozen_string_literal: true

# Copyright © 2019 BigBlueButton Inc. and by respective authors.
#
# This file is part of the BigBlueButton open source conferencing system.
#
# BigBlueButton is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the
# Free Software Foundation, either version 3 of the License, or (at your
# option) any later version.
#
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with BigBlueButton.  If not, see <https://www.gnu.org/licenses/>.

require 'rubygems'
require 'bundler/setup'

require 'optparse'
require 'journald/logger'

# Parse command-line options

recording_id = nil
OptionParser.new do |opts|
  opts.on('--record-id=REC', 'Recording ID to copy captions into') do |rec|
    recording_id = rec
  end
end.parse!

unless recording_id
  warn('--record-id was not specified')
  exit(1)
end

# Read configuration and set up logger

props = File.open(File.expand_path('../bigbluebutton.yml', __dir__)) do |bbb_yml|
  YAML.safe_load(bbb_yml)
end
presentation_props = File.open(File.expand_path('../presentation.yml', __dir__)) do |pres_yml|
  YAML.safe_load(pres_yml)
end

filepathPresOverride = "/etc/bigbluebutton/recording/presentation.yml"
isThereOverride = File.file?(filepathPresOverride)
if (isThereOverride)
  presOverrideProps = YAML::load(File.open(filepathPresOverride))
  presentation_props = presentation_props.merge(presOverrideProps)
end

logger = Journald::Logger.new('caption/presentation')
logger.tag(record_id: recording_id)

captions_dir = props['captions_dir']
publish_dir = presentation_props['publish_dir']

unless captions_dir
  logger.error('captions_dir was not defined in bigbluebutton.yml')
  exit(1)
end

unless File.directory?(File.join(publish_dir, recording_id))
  logger.error('Published recording directory for this recording does not exist')
  exit(0)
end

# Load the captions index file and recording playback caption list

begin
  logger.info('Loading recording playback captions list')
  playback_captions_path = File.join(publish_dir, recording_id, 'captions.json')
  playback_captions = File.open(playback_captions_path) do |json|
    JSON.parse(json.read)
  end
rescue Errno::ENOENT
  logger.info("Playback doesn't have a captions.json - old playback format version?")
  logger.info('Triggering recording reprocessing.')
  archive_done_file = ''
  File.open(archive_done_file, 'w') do |archive_done|
    archive_done.write('Reprocessing for captions')
  end
  # Treat this as success, the captions will be integrated during reprocessing
  exit(0)
end

# Captions index file
begin
  logger.info('Loading captions index file')
  captions_path = File.join(captions_dir, recording_id, 'captions.json')
  captions = File.open(captions_path) do |json|
    JSON.parse(json.read)
  end
rescue Errno::ENOENT
  captions = []
end

# Copy the new caption files over the existing ones in the playback

captions.each do |caption|
  kind = caption['kind']
  lang = caption['lang']
  label = caption['label']

  # TODO: the presentation playback format needs to be updated to support
  # kind != captions
  next unless kind == 'captions'

  logger.info("Copying file for kind=#{kind} lang=#{lang}")
  dest_kind = case kind
              when 'captions' then 'caption'
              else kind
              end

  FileUtils.cp(
    File.join(captions_dir, recording_id, "#{kind}_#{lang}.vtt"),
    File.join(publish_dir, recording_id, "#{dest_kind}_#{lang}.vtt")
  )

  # Remove any existing matching tracks from the playback captions list...
  playback_captions.reject! do |playback_caption|
    playback_caption['locale'] == lang && (
      playback_caption['kind'] == kind ||
      (playback_caption['kind'].nil? && kind == 'captions')
    )
  end
  # ...and add the new one.
  playback_captions << {
    'kind'       => kind,
    'locale'     => lang,
    'localeName' => label,
  }
end

# Save the updated playback captions list

logger.info('Saving updated playback captions list')
# Sort the list by label so the selection menu looks nice
playback_captions.sort { |a, b| a['localeName'] <=> b['localeName'] }
File.open(playback_captions_path, 'w') do |json|
  json.write(JSON.pretty_generate(playback_captions))
end
