;;; -*- Emacs-Lisp -*-

(defvar riece-modules
  (cons 'riece-compat
	(cons (if (featurep 'xemacs)
		  'riece-xemacs
		'riece-emacs)
	      '(riece-globals
		riece-options
		riece-debug
		riece-package-info
		riece-version
		riece-coding
		riece-complete
		riece-addon-modules
		riece-addon
		riece-ruby
		riece-cache

		riece-mode
		;; riece-identity -+-> riece-channel
		;;                 +-> riece-user
		riece-identity
		riece-channel
		riece-user

		riece-misc
		riece-signal

		;; riece-layout ---> riece-display
		riece-layout
		riece-display
		riece-server

		;; riece-channel -+-> riece-naming
		;; riece-user    -+
		riece-naming
		riece-message

		;; riece-filter calls riece-{handle,000,200,300,400,500}
		riece-filter
		riece-handle
		riece-000
		riece-200
		riece-300
		riece-400
		riece-500

		riece-commands
		riece-irc
		riece))))

(defvar riece-mcat-modules
  '(riece-mcat-japanese))

(defvar riece-generated-modules
  '(riece-package-info))

(defvar riece-icons
  '("riece-command-previous-channel.xpm"
    "riece-command-next-channel.xpm"
    "riece-command-configure-windows.xpm"
    "riece-command-list-addons.xpm"
    "riece-command-join.xpm"
    "riece-command-part.xpm"))

(defvar riece-scripts
  '("server.rb"
    "aproxy.rb"))

(defun riece-byte-compile-dest-file-function (filename)
  (expand-file-name
   (concat (file-name-nondirectory filename) "c")))

(defun riece-compile-modules (modules srcdir)
  (let ((load-path (cons nil (cons srcdir load-path)))
	error-modules)
    (while modules
      (let ((source (expand-file-name
		     (concat (symbol-name (car modules)) ".el")
		     srcdir))
	    (binary (expand-file-name
		     (concat (symbol-name (car modules)) ".elc"))))
	(if (file-newer-than-file-p source binary)
	    (condition-case error
		(let ((byte-compile-dest-file-function
		       #'riece-byte-compile-dest-file-function))
		  (byte-compile-file source))
	      (error
	       (setq error-modules (cons (car modules) error-modules))))))
      (setq modules (cdr modules)))
    (if error-modules
	(princ (concat "\n\
  WARNING: ---------------------------------------------------------
  WARNING: Couldn't compile following modules:
  WARNING: 
  WARNING:   " (mapconcat #'symbol-name error-modules ", ") "\n\
  WARNING: 
  WARNING: You should probably stop here, try \"make distclean\" to clear
  WARNING: the last build, and then reconfigure.
  WARNING: ---------------------------------------------------------\n\n")))))

(defun riece-compile-module ()
  (let ((load-path (cons nil load-path)))
    (let ((source (expand-file-name
		   (concat (car command-line-args-left) ".el"))))
      (if (file-newer-than-file-p source (concat source "c"))
	  (byte-compile-file source))))
  ;; Workaround for an XEmacs 21.5 bug ("xemacs -batch -f <func> <arg1>"
  ;; attempts to open <arg1> as a file after <func>).
  (setq command-line-args-left (cdr command-line-args-left)))

(defun riece-install-modules (modules srcdir lispdir just-print)
  (unless (or just-print (file-exists-p lispdir))
    (make-directory lispdir t))
  ;; Workaround for "make distcheck"
  (set-file-modes lispdir 493)
  (while modules
    (let ((name (symbol-name (car modules))))
      (princ (format "%s.el -> %s\n" name lispdir))
      (unless just-print
	(copy-file (expand-file-name
		    (concat name ".el")
		    (if (memq (car modules) riece-generated-modules)
			nil
		      srcdir))
		   (expand-file-name (concat name ".el") lispdir)
		   t t))
      (princ (format "%s.elc -> %s\n" name lispdir))
      (unless just-print
	(if (file-exists-p (expand-file-name (concat name ".elc")))
	    (copy-file (expand-file-name (concat name ".elc"))
		       (expand-file-name (concat name ".elc") lispdir)
		       t t)
	  (princ (format "(%s was not successfully compiled, ignored)\n"
			 name)))))
    (setq modules (cdr modules))))

(defun riece-install-icons (icons srcdir lispdir just-print)
  (unless (or just-print (file-exists-p lispdir))
    (make-directory lispdir t))
  ;; Workaround for "make distcheck"
  (set-file-modes lispdir 493)
  (while icons
    (when (file-exists-p (expand-file-name (car icons) srcdir))
      (princ (format "%s -> %s\n" (car icons) lispdir))
      (unless just-print
	(copy-file (expand-file-name (car icons) srcdir)
		   (expand-file-name (car icons) lispdir)
		   t t)))
    (setq icons (cdr icons))))

(defun riece-install-scripts (scripts srcdir lispdir just-print)
  (unless (or just-print (file-exists-p lispdir))
    (make-directory lispdir t))
  ;; Workaround for "make distcheck"
  (set-file-modes lispdir 493)
  (while scripts
    (when (file-exists-p (expand-file-name (car scripts) srcdir))
      (princ (format "%s -> %s\n" (car scripts) lispdir))
      (unless just-print
	(copy-file (expand-file-name (car scripts) srcdir)
		   (expand-file-name (car scripts) lispdir)
		   t t)))
    (setq scripts (cdr scripts))))

(defun riece-install-just-print-p ()
  (let ((flag (getenv "MAKEFLAGS"))
	case-fold-search)
    (if flag
	(string-match "^\\(\\(--[^ ]+ \\)+-\\|[^ =-]\\)*n" flag))))

(defun riece-examine-modules (srcdir)
  (let ((load-path (cons nil (cons srcdir load-path))))
    (require 'riece-mcat)
    (require 'riece-addon-modules)
    (append riece-modules
	    riece-mcat-modules
	    (mapcar #'car riece-addon-modules))))

(defun riece-examine ()
  (princ (mapconcat #'symbol-name
		    (riece-examine-modules (car command-line-args-left))
		    " ")))

(defun riece-update-mcat ()
  (let* ((srcdir (car command-line-args-left))
	 (modules (riece-examine-modules srcdir))
	 (pointer riece-mcat-modules)
	 files)
    (while pointer
      (setq modules (delq (car pointer) modules)
	    pointer (cdr pointer)))
    (setq files (mapcar (lambda (module)
			  (concat (symbol-name module) ".el"))
			modules)
	  pointer riece-mcat-modules)
    (while pointer
      (riece-mcat-update files (concat (symbol-name (car pointer)) ".el")
			 (intern (concat (symbol-name (car pointer))
					 "-alist")))
      (setq pointer (cdr pointer))))
  ;; Workaround for an XEmacs 21.5 bug ("xemacs -batch -f <func> <arg1>"
  ;; attempts to open <arg1> as a file after <func>).
  (setq command-line-args-left (cdr command-line-args-left)))

(defun riece-compile ()
  (let ((srcdir (car command-line-args-left)))
    (setq command-line-args-left (cdr command-line-args-left))
    (riece-compile-modules (riece-examine-modules srcdir) srcdir))
  ;; Workaround for an XEmacs 21.5 bug ("xemacs -batch -f <func> <arg1>"
  ;; attempts to open <arg1> as a file after <func>).
  (setq command-line-args-left (cdr command-line-args-left)))

(defun riece-install ()
  (let ((srcdir (car command-line-args-left))
	(lispdir (nth 1 command-line-args-left)))
    (riece-install-modules
     (riece-examine-modules srcdir)
     srcdir
     (expand-file-name "riece" lispdir)
     (riece-install-just-print-p))
    (riece-install-icons
     riece-icons
     srcdir
     (expand-file-name "riece" lispdir)
     (riece-install-just-print-p))
    (riece-install-scripts
     riece-scripts
     srcdir
     (expand-file-name "riece" lispdir)
     (riece-install-just-print-p))
    ;; Workaround for an XEmacs 21.5 bug ("xemacs -batch -f <func> <arg1>"
    ;; attempts to open <arg1> as a file after <func>).
    (setq command-line-args-left (nthcdr 2 command-line-args-left))))

(defun riece-uninstall ()
  (let ((files (directory-files (expand-file-name "riece"
						  (car command-line-args-left))
				t "\\.\\(elc?\\|rb\\|xpm\\)$")))
    (while files
      (delete-file (car files))
      (setq files (cdr files)))
    ;; Workaround for an XEmacs 21.5 bug ("xemacs -batch -f <func> <arg1>"
    ;; attempts to open <arg1> as a file after <func>).
    (setq command-line-args-left (cdr command-line-args-left))))

(defun riece-compile-package ()
  (let ((srcdir (car command-line-args-left)))
    (setq command-line-args-left (cdr command-line-args-left))
    (if (fboundp 'batch-update-directory-autoloads)
	(let ((command-line-args-left (list "riece" srcdir)))
	  (batch-update-directory-autoloads))
      (let ((command-line-args-left (list srcdir)))
	(setq autoload-package-name "riece")
	(batch-update-autoloads)))
    (let ((command-line-args-left (list srcdir)))
      (Custom-make-dependencies))
    (riece-compile-modules
     (append (riece-examine-modules srcdir)
	     '(auto-autoloads custom-load))
     srcdir)))

(defun riece-install-package ()
  (let ((srcdir (car command-line-args-left)))
    (setq command-line-args-left (cdr command-line-args-left))
    (riece-install-modules
     (append (riece-examine-modules srcdir)
	     '(auto-autoloads custom-load))
     srcdir
     (expand-file-name "lisp/riece" (car command-line-args-left))
     (riece-install-just-print-p))
    (riece-install-icons
     riece-icons
     srcdir
     (expand-file-name "etc/riece" (car command-line-args-left))
     (riece-install-just-print-p))
    (riece-install-scripts
     riece-scripts
     srcdir
     (expand-file-name "etc/riece" (car command-line-args-left))
     (riece-install-just-print-p))))

(defun riece-test ()
  (let* ((srcdir (car command-line-args-left))
	 (load-path (cons (expand-file-name "test" srcdir)
			  (cons srcdir (cons nil load-path))))
	 (files (directory-files (expand-file-name "test" srcdir) t
				 "^test-.*\\.el$"))
	 suite)
    (require 'lunit-report)
    (setq suite (lunit-make-test-suite))
    (while files
      (when (file-regular-p (car files))
	(load-file (car files))
	(lunit-test-suite-add-test
	 suite
	 (lunit-make-test-suite-from-class
	  (intern (file-name-sans-extension
		   (file-name-nondirectory (car files)))))))
      (setq files (cdr files)))
    (lunit-report suite (nth 1 command-line-args-left))))
