#!/usr/bin/tclsh

# fly2org - flyspray tasks to org-mode

# Copyright (C) 2008 Free Software Foundation, Inc.

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.


set title "GNU PDF Tasks"
set user jemarch
set project "GNU PDF Library"
set dbname mydbname
set dbhost mydbhost
set dbuser mydbuser
set dbpass mydbpassword
set db {}

package require mysqltcl

proc connect_to_database {} {

    global db
    global dbhost
    global dbuser
    global dbpass
    global dbname

    if { [catch {set db [::mysql::connect \
                             -host $dbhost \
                             -user $dbuser \
                             -password $dbpass \
                             -db $dbname]}] } then {
        puts "Error connecting to the mysql database"
        exit
    }
}

proc disconnect_from_database {} {

    global db

    ::mysql::close $db
}

proc format_date {number} {
    return [clock format $number -format \
               "%Y-%m-%d %a"]
}

proc text_lines {text} {

    return [string map {
} $text]
}

proc get_task_list {} {
    global db
    global user
    global project
    
    set sql \
    "select item_summary,
            is_closed,
            date_opened,
            detailed_desc,
            date_closed,
            item_status,
            resolution_reason,
            opened_by,
            percent_complete,
            closed_by
     from
       flyspray_tasks inner join flyspray_users
       on flyspray_tasks.opened_by = flyspray_users.user_id

       inner join flyspray_projects
       on flyspray_tasks.project_id = flyspray_projects.project_id

       where flyspray_users.user_name like '$user' and
             flyspray_projects.project_title like '$project';"

    return [::mysql::sel $db $sql -list]
}

proc get_task_summary {task} {

    return [lindex $task 0]
}

proc get_task_is_closed {task} {

    return [lindex $task 1]

}

proc get_task_date_opened {task} {
    
    return [format_date [lindex $task 2]]
}

proc get_task_detailed_desc {task} {
    return [lindex $task 3]
}

proc get_task_date_closed {task} {
    
    return [format_date [lindex $task 4]]
}

proc get_task_status {task} {
    global db

    return [::mysql::sel $db \
                "select status_name from flyspray_list_status
                 where status_id = [lindex $task 5];" \
                -flatlist]
}

proc get_task_resolution {task} {
    global db

    return [::mysql::sel $db \
                "select resolution_name from flyspray_list_resolution
                 where resolution_id = [lindex $task 6];" \
                -flatlist]
}

proc get_task_opened_by {task} {
    
    global db

    return [::mysql::sel $db \
                "select user_name from flyspray_users
                 where user_id = [lindex $task 7]" \
                -flatlist]
}

proc get_task_closed_by {task} {

    global db

    set closed_by [lindex $task 9]
    if {$closed_by != 0} then {
        return [::mysql::sel $db \
                    "select user_name from flyspray_users
                     where user_id = $closed_by;" \
                    -flatlist]
    } else {
        return ""
    }
}

proc get_task_percent_complete {task} {

    return [lindex $task 8]
}

proc get_status_names {} {
    
    global db
    global project

    return [::mysql::sel $db \
                "select status_name
                 from
                 flyspray_list_status inner join flyspray_projects
                 on flyspray_list_status.project_id = flyspray_projects.project_id
                 where project_title like '$project' and show_in_list = 1;" -list]
}

proc get_resolution_names {} {
    
    global db
    global project

    return [::mysql::sel $db \
                "select resolution_name
                 from
                 flyspray_list_resolution inner join flyspray_projects
                 on flyspray_list_resolution.project_id = flyspray_projects.project_id
                 where project_title like '$project' and show_in_list = 1;" -list]
}

proc get_project_list {} {

    global db

    return [::mysql::sel $db \
                "select project_title from flyspray_projects
                 where project_is_active = 1;" \
                -flatlist]
}

proc generate_project {project_name} {

    global project

    set project $project_name
    
    puts "* $project"
    foreach task [get_task_list] {

        set task_opened_by_name [get_task_opened_by $task]
        set task_closed_by [get_task_closed_by $task]

        if {[get_task_is_closed $task]} then {
            # Get the resolution name
            set task_item_status_name [get_task_resolution $task]
        } else {
            # Get the item status name
            set task_item_status_name [get_task_status $task]
        }

        puts "** $task_item_status_name [get_task_summary $task]"
        puts "   \[[get_task_date_opened $task]\]"
        puts "   :PROPERTIES:"
        puts "   :OpenedBy: $task_opened_by_name"
        if {$task_closed_by != ""} then {
            puts "   :ClosedBy: $task_closed_by"
        }  
        puts "   :PercentComplete: [get_task_percent_complete $task]"
        puts "   :END:"
        puts ""
        puts [text_lines [get_task_detailed_desc $task]]
    }
}

proc generate_projects {} {

    foreach project [get_project_list] {
        generate_project $project
    }
}

proc generate_prolog {} {

    global title

    puts "-*- mode: org; fill-column: 78 -*-"
    puts ""
    puts $title
    puts "Generated at [clock format [clock seconds]] by fly2org"
    puts ""
}

proc generate_epilog {} {

    puts "* Epilog"
    # Write down the categories
    puts ""
    puts -nonewline "#+SEQ_TODO: "
    foreach status_name [get_status_names] {
        puts -nonewline "[lindex $status_name 0] "
    }
    puts -nonewline "| "
    foreach resolution_reason [get_resolution_names] {
        puts -nonewline "[lindex $resolution_reason 0] "
    }
    puts ""
}

proc main {} {
    
    global db

    connect_to_database

    ;# Generate the contents
    generate_prolog
    generate_projects
    generate_epilog

    disconnect_from_database
}


# Call the main procedure
main

# End of fly2org
