####################################################################################
##                                                                                ##
##  I N T E R S T E L L A R   C O N S O L E  Info Server                          ##
##                                                                                ##
##            Copyright (C) 2025- Misato Observatory, Wakayama, Japan             ##
##                                                                                ##
##  This software is available under the GPL (General Public License)             ##
##                                                                                ##
##  References:                                                                   ##
##  https://mibai.tec.u-ryukyu.ac.jp/~oshiro/Doc/tcltk_primer/socket-sample.html  ##
##                                                                                ##
####################################################################################

set server_root "."
set port_number 8091

proc add_a_server { sock addr port } {
    fileevent $sock readable "server_handler $sock"
    fconfigure $sock -buffering line
}

proc server_handler { sock } {

  global server_root

  # Read request and header of a client
  #
  set request_str [string trim [gets $sock]]
  while 1 {
    set header_str [string trim [gets $sock]]
    if { [string length $header_str] == 0 } {
      break
    }
  }

  # Check request
  #
  set request_list [split $request_str " "]
  set bad_request 0
  set flg_server_test 0
  if { [llength $request_list] < 2 } {
    set bad_request 1
  } else {
    if { [lindex $request_list 0] ne "GET" } {
      set bad_request 1
    } else {
      set requested_file $server_root
      set fname [lindex $request_list 1]
      #puts $fname
      append requested_file $fname
      if { $fname eq "/" } {
        set flg_server_test 1
      }
    }
  }

  # Response
  #
  if { [eof $sock] } {
    close $sock
  } else {
    if { $flg_server_test != 0 } {
      puts -nonewline $sock "HTTP/1.0 200 OK\r\n"
      puts -nonewline $sock "Server: ISC Info Server\r\n"
      puts -nonewline $sock "Content-Type: text/plain\r\n"
      puts -nonewline $sock "\r\n"
      puts $sock "ok"
      puts "200 GET: test ok"
    } elseif { $bad_request != 0 } {
      puts -nonewline $sock "HTTP/1.0 501 Not Implemented Error\r\n"
      puts -nonewline $sock "\r\n"
      puts "501 ERROR"
    } elseif { [catch {open $requested_file r} fh] } {
      puts -nonewline $sock "HTTP/1.0 404 Not Found\r\n"
      puts -nonewline $sock "\r\n"
      puts "404 ERROR"
    } else {
      #
      puts -nonewline $sock "HTTP/1.0 200 OK\r\n"
      puts -nonewline $sock "Server: ISC Info Server\r\n"
      puts -nonewline $sock "Content-Type: text/plain\r\n"
      puts -nonewline $sock "\r\n"
      puts "200 GET: '$requested_file'"
      #
      while { [gets $fh txt_line] >= 0 } {
        puts $sock "$txt_line"
      }
      close $fh
    }
    close $sock
  }

}

if { 0 < $argc } {
  set server_root [regsub -all {\\} [lindex $argv 0] {/}]
}
if { 1 < $argc } {
  set port_number [lindex $argv 1]
}

puts "// Interstellar Console Info Server //"
puts "server_root: $server_root"
puts "port_number: $port_number"
puts ""

socket -server add_a_server $port_number

vwait forever

