#!/bin/bash

##########################################################
# Copyright (c) 2001-2025 Alexey Kuryakin daqgroup@mail.ru
##########################################################

##########################################################
# Utility to print MIME file association, default handler.
# References:
# 1) XDG Desktop Menu Specification.
# 2) XDG Base Directory Specification.
# 3) XDG Icon Theme Specification.
# 4) XDG Icon Naming Specification.
# 5) XDG Shared MIME-info Database.
# 6) XDG Desktop Entry Specification.
##########################################################

################################
# Current script identification.
################################
readonly startupdir="$(pwd -LP)";
readonly scriptfile="${BASH_SOURCE[0]}";
readonly scriptname="$(basename $scriptfile)";
readonly scriptbase="$(basename $scriptfile .sh)";
readonly scripthome="$(dirname  $scriptfile)";
readonly scriptFILE="$(realpath $scriptfile)";
readonly scriptHOME="$(dirname  $scriptFILE)";

source "$scriptHOME/ftype.in";

function do_version(){
 echo "$scriptname version 1.0";
};

function do_print_help(){
 do_version;
cat<<EOF
$scriptname Copyright (c) 2025 Alexey Kuryakin daqgroup@mail.ru
Utility to print MIME associated handlers.
Usage:
 $scriptname [-options] [mime [params]]
Options:
 --version  - print version
 -h,--help  - print help screen
 -d,--def   - print default handler - .desktop file
 -p,--path  - print full file path of .desktop file
 -e,--exec  - print Exec parameter of .desktop file
 -i,--icon  - print Icon parameter of .desktop file
 -L,--Link  - follow i.e. dereference .desktop file link
 -c,--cmd   - print command line with substituted params
Parameters:
 mime       - MIME type to print association
 params     - arguments for command line with option --cmd
Examples:
 $scriptname                # print list of all known MIME type associations
 $scriptname text/html      # print associated handlers  for MIME type text/html
 $scriptname -d text/html   # print default handler      for MIME type text/html
 $scriptname -p text/html   # print associated file path for MIME type text/html
 $scriptname -e text/html   # print associated Exec      for MIME type text/html
 $scriptname -c text/html f # print command line to open file (f) as text/html
 $scriptname --help         # print help screen
 $scriptname --version      # print version
EOF
};

function cat_mime_list_section(){
 if [[ -n $1 ]]; then
  local section="$1";
  for f in $(enum_mime_list_files); do
   read_inifile_section "$f" "$section";
  done;
 fi;
};

function cat_added_associations()   { cat_mime_list_section "[Added Associations]";   };
function cat_default_applications() { cat_mime_list_section "[Default Applications]"; };
function cat_removed_associations() { cat_mime_list_section "[Removed Associations]"; };

function grep_opt_removed(){
 for item in $(cat_removed_associations); do
  echo -n " -e $item";
 done;
};

function cat_all_applications(){
 cat_default_applications;
 cat_added_associations;
};

function print_all_applications(){
 local opt="$(grep_opt_removed)";
 cat_all_applications | grep -v -x ${opt:-NONE} | sort -u;
};

function ftype_list(){
 print_all_applications;
};

function ftp_def_app(){
 ftype_list | grep -e "^$1=" | sed 's/.*=//' | tail -n1;
};

function query_default_app(){
 local mime="$1"; local app="";
 if [[ -z $mime ]]; then return 1; fi;
 if [[ -z $app ]]; then app="$(sys_def_app "$mime")"; fi;
 if [[ -z $app ]]; then app="$(ftp_def_app "$mime")"; fi;
 if [[ -n $app ]]; then echo "$app"; return 0; fi;
 return 1;
};

function fallback_icon(){
 local app="";
 for app in $(ftype_list | grep -e "^$1=" | sed 's/.*=//' | tac); do
  local fapp="$(find_app_handler $app)";
  local ico="$(unix $readini "$fapp" "[Desktop Entry]" "Icon" | sed 's/.*=//')";
  if [[ -n $ico ]]; then echo "$ico"; return 0; fi;
 done;
 return 1;
};

function print_ftype(){
 if [[ -z $1 ]]; then
  ftype_list;
  return;
 else
  while [[ -n $1 ]]; do
   if [[ $opt_path -eq 1 ]] || [[ $opt_exec -eq 1 ]] || [[ $opt_icon -eq 1 ]] || [[ $opt_def -eq 1 ]]; then
    local line="";
    local app="$(query_default_app "$1")";
    if [[ -n $app ]]; then
     local fapp="$(find_app_handler $app)";
     if [[ -e $fapp ]]; then
      if [[ $opt_exec -eq 1 ]] && [[ -z $line ]]; then
       local exe="$(unix $readini "$fapp" "[Desktop Entry]" "Exec" | sed 's/.*=//')";
       if [[ -n $exe ]]; then line="$1=$exe"; else return 1; fi;
       if [[ $opt_cmd -eq 1 ]] && [[ -n $exe ]]; then
        echo -n "$1="; shift; subst_exec_args "$exe" "$@"; return;
       fi;
      fi;
      if [[ $opt_icon -eq 1 ]] && [[ -z $line ]]; then
       local ico="$(unix $readini "$fapp" "[Desktop Entry]" "Icon" | sed 's/.*=//')";
       if [[ -z $ico ]]; then ico="$(fallback_icon "$1")"; fi;
       if [[ -n $ico ]]; then line="$1=$ico"; else return 1; fi;
      fi;
      if [[ -z $line ]] && [[ $opt_path -eq 0 ]] && [[ $opt_exec -eq 0 ]] && [[ $opt_icon -eq 0 ]]; then
       line="$1=$app";
      fi;
      if [[ -z $line ]]; then
       line="$1=$fapp";
      fi;
     else
      return 1;
     fi;
    else
     return 1;
    fi;
    if [[ -n $line ]]; then echo "$line"; fi;
    shift;
    continue;
   fi;
   if ftype_list | grep -e "^$1="; then
    skip;
   else
    return 1;
   fi;
   shift;
  done;
 fi;
};

######
# MAIN
######

function main(){
 check_readini;
 while [[ -n $1 ]]; do
  case $1 in
   --version)       do_version; return 0; ;;
   -h|-help|--help) do_print_help; return 0; ;;
   -e|-exec|--exec) let opt_exec=1; ;;
   -i|-icon|--icon) let opt_icon=1; ;;
   -p|-path|--path) let opt_path=1; ;;
   -L|-Link|--Link) let opt_link=1; ;;
   -d|-def|--def)   let opt_def=1; ;;
   -c|-cmd|--cmd)   let opt_exec=1; let opt_cmd=1; ;;
   -*)              fatal 1 "Error: bad option $1"; ;;
   *)               break; ;;
  esac;
  shift;
 done;
 print_ftype "$@";
};

main "$@";

##############
## END OF FILE
##############
