#!/usr/bin/env tclsh
###############################################################################
# BRLTTY - A background process providing access to the console screen (when in
#          text mode) for a blind person using a refreshable braille display.
#
# Copyright (C) 1995-2023 by The BRLTTY Developers.
#
# BRLTTY comes with ABSOLUTELY NO WARRANTY.
#
# This is free software, placed under the terms of the
# GNU Lesser General Public License, as published by the Free Software
# Foundation; either version 2.1 of the License, or (at your option) any
# later version. Please see the file LICENSE-LGPL for details.
#
# Web Page: http://brltty.app/
#
# This software is maintained by Dave Mielke <dave@mielke.cc>.
###############################################################################

source [file join [file dirname [info script]] .. prologue.tcl]
source [file join $scriptDirectory csv.tcl]

set optionDefinitions {
   {test      flag "don't update the files"}
}

processProgramArguments optionValues $optionDefinitions
cd [file join $sourceRoot $documentsSubdirectory]

array set tableHeaders {
   braille-driver {code name aliases others}
   speech-driver  {code name aliases}
   screen-driver  {code name}

   text-table        {name description}
   contraction-table {name description}
   attributes-table  {name description}
   keyboard-table    {name description}
}

proc makeLists {file} {
   set lists [dict create]
   set pattern {^#(\w+-(?:driver|table))\s+([-\w]+)\s*#\s*(.*?)\s*$}

   forEachLine line $file {
      if {[regexp $pattern $line x directive operand comment]} {
         dict lappend lists [string tolower $directive] [linsert [lmap column [split $comment ";"] {string trim $column}] 0 $operand]
      }
   }

   return $lists
}

proc updateTable {lists name} {
   global tableHeaders

   if {[info exists tableHeaders($name)]} {
      set headers $tableHeaders($name)
      set rows [csvNormalizeRows [linsert [dict get $lists $name] 0 $headers] [llength $headers]]

      if {[regexp {^(.*)-driver$} $name x driverType]} {
         set usageColumn [list usage]
         set driversDirectory [file join $::sourceRoot $::driversSubdirectory [string totitle $driverType]]

         foreach columns [lrange $rows 1 end] {
            set driverName [lindex $columns 1]
            set makeFile [file join $driversDirectory $driverName Makefile.in]

            if {[file exists $makeFile]} {
               set driverUsage [getMakeFileProperty $makeFile DRIVER_USAGE]
            } else {
               set driverUsage ""
            }

            lappend usageColumn $driverUsage
         }

         set rows [lmap columns $rows usage $usageColumn {
            linsert $columns end $usage
         }]
      }

      if {[updateFile "$name.csv" [csvMakeTable $rows] $::optionValues(test)]} {
         return 1
      }
   } else {
      logWarning "table headers not defined: $name"
   }

   return 0
}

proc updateTables {lists} {
   set updated 0

   foreach name [dict keys $lists] {
      if {[updateTable $lists $name]} {
         set updated 1
      }
   }

   return $updated
}

if {![updateTables [makeLists "brltty.conf.in"]]} {
   logMessage task "no files updated"
}

exit 0
