#!/bin/bash

#########################################################################
# ks-mp3 (ks-tools) - Convert video/audio file(s) to MP3 (Audio) Format #
# Date: 01-10-2023                                                      #
# Author: q3aql                                                         #
# Contact: q3aql@duck.com                                               #
#########################################################################
VERSION="8.5-dev"
M_DATE="011023"

# Global parameters
dirTemp="/tmp"
listTemp="ks-tools.list"
ksToolsTempFolder="/tmp/ks-tools"
configFolder=${HOME}/.ks-tools 
configFile=${configFolder}/ks-mp3

# Basic parameters
acodec="libmp3lame"
b_acodec="128k"
v_ext="mp3"
default_lang_audio="spa"

# Check cygwin alias (for Windows)
if [ -f "/usr/bin/cygwin-alias.sh" ] ; then
  shopt -s expand_aliases
  source "/usr/bin/cygwin-alias.sh"
fi

# Create inicial config file
mkdir -p ${configFolder}
if [ -f ${configFile} ] ; then
  exist_acodec=$(cat ${configFile} | grep "acodec" | cut -c2 | cut -d "_" -f 1) 
  exist_b_acodec=$(cat ${configFile} | grep "b_acodec=") 
  exist_default_lang_audio=$(cat ${configFile} | grep "default_lang_audio=") 
  exist_v_ext=$(cat ${configFile} | grep "v_ext=")
  if [ -z ${exist_acodec} ] ; then
    echo "acodec=${acodec}" >> ${configFile}
  fi
  if [ -z ${exist_b_acodec} ] ; then
    echo "b_acodec=${b_acodec}" >> ${configFile}
  fi
  if [ -z ${exist_default_lang_audio} ] ; then
    echo "default_lang_audio=${default_lang_audio}" >> ${configFile}
  fi
  if [ -z ${exist_v_ext} ] ; then
    echo "v_ext=${v_ext}" >> ${configFile}
  fi
  source ${configFile}
else
  echo "#!/bin/bash" > ${configFile}
  echo "" >> ${configFile}
  echo "acodec=${acodec}" >> ${configFile}
  echo "b_acodec=${b_acodec}" >> ${configFile}
  echo "default_lang_audio=${default_lang_audio}" >> ${configFile}
  echo "v_ext=${v_ext}" >> ${configFile}
  source ${configFile}
fi

# Check if ffmpeg is installed
path_check="/usr/bin /bin /usr/local/bin ${HOME}/.local/bin $(brew --prefix)/bin"
dependencies="ffmpeg grep sed grep cut head tail tr cat"
dependencies_found=""
dependencies_not_found=""
for checkPath in ${path_check} ; do
  for checkDependencies in ${dependencies} ; do
    if [ -f ${checkPath}/${checkDependencies} ] ; then
      dependencies_found="${dependencies_found} ${checkDependencies}"
    fi
  done
done
for notFound in ${dependencies} ; do
  check_found_one=$(echo ${dependencies_found} | grep " ${notFound}")
  check_found_two=$(echo ${dependencies_found} | grep "${notFound} ")
  if_not_found="${check_found_one}${check_found_two}"
  if [ -z "${if_not_found}" ] ; then
    dependencies_not_found="${dependencies_not_found} ${notFound}"
  fi
done
# Show if all tools are installed
if [ -z "${dependencies_not_found}" ] ; then
  echo > /dev/null
else
  echo ""
  echo "* ks-mp3 (ks-tools) v${VERSION} (${M_DATE})"
  echo ""
  echo "* Some required tools are not installed:${dependencies_not_found}"
  echo "* The process has been stopped"
  echo ""
  exit
fi

# Funcion to show the name of file/folder from full path
# Syntax: extractFolderOrFile <full/path/file.txt>
function extractFolderOrFile() {
  pathToExtract="${1}/"
  findFolder=0
  count=1
  nameFolder=$(echo ${pathToExtract} | cut -d "/" -f ${count})
  count=$(expr $count + 1)
  while [ ${findFolder} -eq 0 ] ; do
    nameFolderTemp=$(echo ${pathToExtract} | cut -d "/" -f ${count})
    if [ -z "${nameFolderTemp}" ] ; then
      findFolder=1
    else
      nameFolder="${nameFolderTemp}"
      count=$(expr $count + 1)
    fi
  done
  echo "${nameFolder}"
}

# Function to remove extension from file
# Syntax: removeExtension "<text>"
function removeExtension() {
  wordToConvert=${1}
  ksToolsSedFile="${ksToolsTempFolder}/ks-tools-${RANDOM}.txt"
  mkdir -p ${ksToolsTempFolder} && chmod 777 -R ${ksToolsTempFolder} 2> /dev/null
  echo "${wordToConvert}" > ${ksToolsSedFile}
  # Remove extensions
  sed -i 's/.avi//g' "${ksToolsSedFile}" &> /dev/null
  sed -i 's/.mp4//g' "${ksToolsSedFile}" &> /dev/null
  sed -i 's/.mkv//g' "${ksToolsSedFile}" &> /dev/null
  sed -i "s/.mov//g" "${ksToolsSedFile}" &> /dev/null
  sed -i 's/.vob//g' "${ksToolsSedFile}" &> /dev/null
  sed -i 's/.mpg//g' "${ksToolsSedFile}" &> /dev/null
  sed -i 's/.mpeg//g' "${ksToolsSedFile}" &> /dev/null
  sed -i 's/.wmv//g' "${ksToolsSedFile}" &> /dev/null
  sed -i 's/.ogv//g' "${ksToolsSedFile}" &> /dev/null
  sed -i 's/.webm//g' "${ksToolsSedFile}" &> /dev/null
  sed -i 's/.flv//g' "${ksToolsSedFile}" &> /dev/null
  sed -i 's/.mp3//g' "${ksToolsSedFile}" &> /dev/null
  sed -i 's/.mp2//g' "${ksToolsSedFile}" &> /dev/null
  sed -i 's/.oga//g' "${ksToolsSedFile}" &> /dev/null
  sed -i 's/.ogg//g' "${ksToolsSedFile}" &> /dev/null
  sed -i 's/.ac3//g' "${ksToolsSedFile}" &> /dev/null
  sed -i 's/.aac//g' "${ksToolsSedFile}" &> /dev/null
  sed -i 's/.flac//g' "${ksToolsSedFile}" &> /dev/null
  sed -i 's/.wav//g' "${ksToolsSedFile}" &> /dev/null
  sed -i 's/.opus//g' "${ksToolsSedFile}" &> /dev/null
  # Show file without extension
  wordToConvert=$(cat ${ksToolsSedFile})
  echo ${wordToConvert}
}

# Function to show files with spaces.
# Syntax: showFileWithSpace <file number>
function showFileWithSpace() {
  echo "${1}" > ${dirTemp}/name.tmp
  sed -i 's/_/ /g' ${dirTemp}/name.tmp
  DisplayName=$(cat ${dirTemp}/name.tmp)
  rm -rf ${dirTemp}/name.tmp
  cutDisplayName=$(echo ${DisplayName} | cut -c1)
  if [ "${cutDisplayName}" == "-" ] ; then
    DisplayName=$(echo ${DisplayName} | cut -c2-100)
  else
    cutDisplayName=$(echo ${DisplayName} | cut -c2)
    if [ "${cutDisplayName}" == "-" ] ; then
      DisplayName=$(echo ${DisplayName} | cut -c3-100)
    else
      cutDisplayName=$(echo ${DisplayName} | cut -c3)
      if [ "${cutDisplayName}" == "-" ] ; then
        DisplayName=$(echo ${DisplayName} | cut -c4-100)
      fi
    fi
  fi
  echo ${DisplayName}
}

# Syntax: ks-mp3 </absolute/path/song.ogg> </path/prefix_name>
if [ -z "${1}" ] ; then
  echo ""
  echo "* ks-mp3 (ks-tools) v${VERSION} (${M_DATE})"
  echo ""
  echo "- Convert video/audio file(s) to MP3 (Audio) Format"
  echo ""
  echo "+ Config: ${configFile}"
  echo ""
  echo " - Audio codec: ${acodec}"
  echo " - Bitrate audio: ${b_acodec}"
  echo " - Container: ${v_ext}"
  echo ""
  echo "+ Syntax: "
  echo ""
  echo "  $ ks-mp3 </absolute/path/song.ogg> </path/prefix_name>"
  echo ""
  echo " + Example: ks-mp3 /data/songs/Example.ogg /data/converted/Example"
  echo ""
  exit
fi
if [ -f "${1}" ] ; then
  echo "detected" > /dev/null
else
  echo ""
  echo "* ks-mp3 (ks-tools) v${VERSION} (${M_DATE})"
  echo ""
  echo "* The file '${1}' does not exist!"
  echo ""
  exit
fi

# Conversion parameters
p_ffmpeg="ffmpeg -i"

# Init conversion file
current_date=$(date +%Y)
if [ -z "${2}" ] ; then
  echo ""
  echo "* ks-mp3 (ks-tools) v${VERSION} (${M_DATE})"
  echo ""
  echo "- Convert video/audio file(s) to MP3 (Audio) Format"
  echo ""
  echo "+ Config:"
  echo ""
  echo " - Audio codec: ${acodec}"
  echo " - Bitrate audio: ${b_acodec}"
  echo " - Container: ${v_ext}"
  echo ""
  echo "+ Syntax: "
  echo ""
  echo "  $ ks-mp3 </absolute/path/song.ogg> </path/prefix_name>"
  echo ""
  echo " + Example: ks-mp3 /data/songs/Example.ogg /data/converted/Example"
  echo ""
  exit
else
  echo ""
  echo "* Information of ${1}:"
  echo ""
  echo "+ Audio Tracks:"
  ${p_ffmpeg} "${1}" 2>&1 | grep Stream | tr -s " " | grep "Audio:" | cut -d "," -f 1
  echo ""

  # Check the audio track by default
  audio_default=$(${p_ffmpeg} "${1}" 2>&1 | grep Stream | tr -s " " | grep "Audio:" | grep "(${default_lang_audio})" | cut -d " " -f 3 | cut -c2-5 | cut -d "(" -f 1 | cut -d "[" -f 1 | head -1)
  if [ -z "${audio_default}" ] ; then
    audio_default=$(${p_ffmpeg} "${1}" 2>&1 | grep Stream | tr -s " " | grep "Audio:" | cut -d " " -f 3 | cut -c2-5 | cut -d "(" -f 1 | cut -d "[" -f 1 | head -1)
    if [ -z "${audio_default}" ] ; then
      audio_default="0:1"
    else
      audio_default_patch=$(echo ${audio_default} | cut -c4)
      if [ "${audio_default_patch}" == ":" ] ; then
        audio_default=$(echo ${audio_default} | cut -c1-3)
      else
        audio_default="${audio_default}"
      fi
    fi
  else
    audio_default_patch=$(echo ${audio_default} | cut -c4)
    if [ "${audio_default_patch}" == ":" ] ; then
      audio_default=$(echo ${audio_default} | cut -c1-3)
    else
      audio_default="${audio_default}"
    fi
  fi
  # Ask for audio
  echo -n "* (Default: ${audio_default}) Type the number of audio track: " ; read audio_track
  if [ -z "${audio_track}" ] ; then
    audio_track="${audio_default}"
  else
    audio_track="${audio_track}"
  fi

  # Ask for METADATA
  echo ""
  echo "* METADATA configuration:"
  echo ""
  # Prepare name title by default
  FullPath="${1}"
  name_title_default=$(extractFolderOrFile "${FullPath}")
  name_title_default=$(removeExtension "${name_title_default}")
  name_title_default=$(showFileWithSpace "${name_title_default}")
  # Ask name title, year and genre
  echo -n "* (Default: ${name_title_default}) Type name of title: " ; read name_title
  if [ -z "${name_title}" ] ; then
    name_title="${name_title_default}"
  else
    name_title="${name_title}"
  fi
  echo -n "* (Default: Album-Disc) Type name of album: " ; read album_file
  if [ -z "${album_file}" ] ; then
    album_title="Album-Disc"
  else
    album_title="${album_file}"
  fi
  echo -n "* (Default: 01) Type number of track: " ; read track_file
  if [ -z "${track_file}" ] ; then
    track_num="01"
  else
    track_num="${track_file}"
  fi
  echo -n "* (Default: Artist) Type name of artist: " ; read artist_file
  if [ -z "${artist_file}" ] ; then
    artist_title="Artist"
  else
    artist_title="${artist_file}"
  fi
  echo -n "* (Default: ${current_date}) Type the year: " ; read year_file
  if [ -z "${year_file}" ] ; then
    year_num="${current_date}"
  else
    year_num="${year_file}"
  fi
  echo -n "* (Default: Pop) Type the genre: " ; read genre_file
  if [ -z "${genre_file}" ] ; then
    genre_file="Pop"
  else
    genre_file="${genre_file}"
  fi

  # Check audio 5.1 or 7.1
  audio_5_7_1=$(${p_ffmpeg} "${1}" 2>&1 | grep Stream | tr -s " " | grep "Audio:" | grep "${audio_track}" | grep -i "5.1")
  audio_5_7_1_2=$(${p_ffmpeg} "${1}" 2>&1 | grep Stream | tr -s " " | grep "Audio:" | grep "${audio_track}" | grep -i "7.1")
  audio_5_7_1="${audio_5_7_1}${audio_5_7_1_2}"
  if [ -z "${audio_5_7_1}" ] ; then
    stereo_params="-ac 2"
  else
    stereo_params="-ac 2 -clev 3dB -slev -6dB"
  fi

  # Show commands for conversion
  echo ""
  echo "* COMMANDS THAT WILL BE EXECUTED:"
  echo ""
  echo "  # Convert the file '${1}' to MP3 Audio"
  echo "  ${p_ffmpeg} \"${1}\" -map ${audio_track} -c:a ${acodec} -b:a ${b_acodec} ${stereo_params} -metadata title=\"${name_title}\" -metadata date=\"${year_num}\" -metadata genre=\"${genre_file}\" -metadata album=\"${album_title}\" -metadata artist=\"${artist_title}\" -metadata track=\"${track_num}\" \"${2}.${v_ext}\""

  # Execute commands for conversion
  echo ""
  echo -n "* (Default: y) Do you want run the conversion? (y/n): " ; read run_commands_ffmpeg
  if [ "${run_commands_ffmpeg}" == "n" ] ; then
    exit
  else
    ${p_ffmpeg} "${1}" -map ${audio_track} -c:a ${acodec} -b:a ${b_acodec} ${stereo_params} -metadata title="${name_title}" -metadata date="${year_num}" -metadata genre="${genre_file}" -metadata album="${album_title}" -metadata artist="${artist_title}" -metadata track="${track_num}" "${2}.${v_ext}"
  fi
fi