(* Copyright 2012 Tony Garnock-Jones <tonygarnockjones@gmail.com>. *)

(* This file is part of Hop. *)

(* Hop 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. *)

(* Hop 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 Hop.  If not, see <http://www.gnu.org/licenses/>. *)

open Lwt

let n_system_log = Node.name_of_string "system.log"

let hook_log () =
  let old_hook = !Log.hook in
  let new_hook label body =
    ignore (Node.post n_system_log (Sexp.Str label) body (Sexp.Str ""));
    old_hook label body
  in
  Log.hook := new_hook

let create_ready_file () =
  match Config.get "ready-file" with
    | Some (Json.Str ready_file_path) ->
      ignore (Log.info "Creating ready file" [Sexp.Str ready_file_path]);
      return (close_out (open_out ready_file_path))
    | Some other ->
      ignore (Log.error "Ready file path not a string" [Sexpjson.sexp_of_json other]);
      return ()
    | None ->
      return ()

let console_watcher () =
  lwt _ = Lwt_io.read_line Lwt_io.stdin in
  Server_control.milestone "Shutdown requested";
  return ()

lwt _ =
  Printf.printf "%s %s, %s\n%s\n%!"
    App_info.product App_info.version App_info.copyright App_info.licence_blurb;
  Sys.set_signal Sys.sigpipe Sys.Signal_ignore;
  Uuid.init ();
  Config.init ();
  lwt () = Factory.init () in
  lwt () = Queuenode.init () in
  lwt () = Fanoutnode.init () in
  lwt () = Directnode.init () in
  lwt () = Meta.init () in
  hook_log ();
  lwt () = Config.conditional "amqp.enabled" true (fun () ->
    ignore (Amqp_relay.init ());
    Server_control.run_until "AMQP ready")
  in
  lwt () = Config.conditional "http.enabled" true (fun () ->
    ignore (Ui_main.init ());
    ignore (Ui_relay.init ());
    Server_control.run_until "HTTP ready")
  in
  lwt () = Config.conditional "hop.enabled" true (fun () ->
    ignore (Relay.init ());
    Server_control.run_until "Hop ready")
  in
  ignore (console_watcher ());
  if Server_control.is_running ()
  then (lwt () = create_ready_file () in
	Server_control.milestone "Server initialized";
	Server_control.run_until "Shutdown requested")
  else return ()
