;;;; -*- Mode: Lisp; Syntax: Common-Lisp; indent-tabs-mode: nil -*-
;;;; vim: set filetype=lisp tabstop=8 shiftwidth=2 expandtab:

;;;
;;; (c) 2011, Juan Jose Garcia-Ripoll
;;;
;;; Set up the test environment.
;;;

(defpackage :ecl-tests
  (:use :cl))

(in-package :ecl-tests)

(setf *load-verbose* nil *load-print* nil)

(defvar *ecl-sources*
  (loop for *default-pathname-defaults* in
        '(#p"/tmp/pkgbuild/lang/ecl/work/ecl-16.1.2/src/" #p"../../" #p"../../src/")
        when (probe-file "configure.ac")
        return *default-pathname-defaults*))

(defvar *test-sources* (merge-pathnames "tests/" *ecl-sources*))

(defvar *here* (merge-pathnames "./"))

(defvar *cache* (merge-pathnames "./cache/" *here*))

(defvar *test-image* (or (ext:getenv "TEST_IMAGE")
                         #+windows
                         (namestring (truename #+windows "sys:ecl.exe"))
                         #-windows
                         "/usr/pkg/bin/ecl"))

(defvar *test-image-args*
  (cond ((search "ecl" *test-image*)
         '("-norc" "-eval" "(print (ext:getenv \"ECLDIR\"))"
           ;#+windows "-eval" #+windows "(require :cmp)"
           ))
        ((search "sbcl" *test-image*)
         '("--no-userinit" "--no-sysinit"))
        (t
         '())))

#+ecl
(ext:setenv "ECLDIR" (namestring (truename "SYS:")))

(defvar *test-name* (or (ext:getenv "TEST_NAME") "ecl"))
(defvar *output-directory* *here*)
(defvar *regressions-sources* (merge-pathnames "regressions/" *test-sources*))
(defvar *regressions-sandbox* (merge-pathnames "regressions/" *here*))
(defvar *wild-inferiors* (make-pathname :name :wild
                                        :type :wild
                                        :version :wild
                                        :directory '(:relative :wild-inferiors)))
(defvar *cleanup-extensions* '("fasl" "fasb" "c" "h" "obj" "o" "a" "lib" "dll" "dylib" "data"))

(defun lisp-system-directory ()
  (loop with root = (si::get-library-pathname)
        with lib-name = (format nil "../lib/ecl-~A/" (lisp-implementation-version))
        for base in (list root (merge-pathnames lib-name root))
        when (or (probe-file (merge-pathnames "./BUILD-STAMP" base))
                 (probe-file (merge-pathnames "./LGPL" base)))
        do (return base)))

(setf (logical-pathname-translations "SYS")
      (list (list #p"sys:**;*.*"
                  (merge-pathnames "**/*.*"
                                   (lisp-system-directory)))))

(require :cmp)

;;;
;;; PREPARATION OF DIRECTORIES AND FILES
;;;

(defun setup-asdf ()
  (require :asdf)
  (ensure-directories-exist *cache*)
  (setf (symbol-value (read-from-string "asdf::*user-cache*"))
        (list *cache* :implementation)))
                      

(defun delete-everything (path)
  ;; Recursively run through children
  (labels ((recursive-deletion (path)
             (mapc #'delete-everything
                   (directory (merge-pathnames
                               (make-pathname :name nil
                                              :type nil
                                              :directory '(:relative :wild)
                                              :defaults path)
                               path)))
             ;; Delete files
             (loop for f in (directory (make-pathname :name :wild
                                                      :type :wild
                                                      :defaults path))
                do (delete-file f)
                finally (delete-file path))))
    (and (probe-file path)
         (recursive-deletion path))))

(defun copy-directory (orig dest)
  (setf orig (truename orig))
  (print dest)
  (loop for f in (directory (merge-pathnames *wild-inferiors* orig))
     for f2 = (enough-namestring f orig)
     for f3 = (merge-pathnames f2 dest)
     unless (and (probe-file f3)
                 (>= (file-write-date f3)
                     (file-write-date f2)))
     do (ensure-directories-exist f3)
     do (ext:copy-file f f3)))

(defun ensure-regressions ()
  (unless (probe-file *regressions-sandbox*)
    (copy-directory *regressions-sources* *regressions-sandbox*)))


(defun cleanup-directory (path)
  (loop for i in (directory (merge-pathnames *wild-inferiors*
                                             path))
     when (member (pathname-type i) *cleanup-extensions* :test #'string-equal)
     do (delete-file i)))

;;;
;;; RUNNING TESTS
;;;

(defun run-regressions-tests ()
  (ensure-regressions)
  ;; Cleanup stray files
  (cleanup-directory *regressions-sandbox*)
  (unwind-protect 
       (progn
         (ext:chdir *regressions-sandbox*)
         (ext:run-program *test-image*
                          *test-image-args*
                          :input (merge-pathnames "doit.lsp" *regressions-sandbox*)
                          :output t
                          :error :output))
    (ext:chdir *here*)))
