;;; Gash -- Guile As SHell
;;; Copyright © 2018 Timothy Sample <samplet@ngyro.com>
;;;
;;; This file is part of Gash.
;;;
;;; Gash 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.
;;;
;;; Gash 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 Gash.  If not, see <http://www.gnu.org/licenses/>.

(use-modules ((gnu packages bash) #:select (bash-minimal))
             (gnu packages bootstrap)
             (guix build-system)
             (guix build-system trivial)
             (guix packages)
             (guix store)
             (guix utils)
             (ice-9 match))

(define gash
  (load (string-append (current-source-directory) "/../../guix.scm")))

(define %bootstrap-gash
  (package
    (inherit gash)
    (build-system trivial-build-system)
    (arguments
     `(#:guile ,%bootstrap-guile
       #:modules ((guix build utils))
       #:builder
       (let* ((out     (assoc-ref %outputs "out"))
              (source (assoc-ref %build-inputs "source"))
              (guile-dir (assoc-ref %build-inputs "guile"))
              (guile (string-append guile-dir "/bin/guile"))
              (moddir (string-append out "/share/guile/site/"
                                     (effective-version)))
              (godir (string-append out "/lib/guile/"
                                    (effective-version) "/site-ccache")))
         (use-modules (guix build utils))
         (format #t "Copying source files~%")
         (copy-recursively source "source" #:log #f)
         (format #t "Entering source directory~%")
         (chdir "source")
         (add-to-load-path (getcwd))
         (format #t "Configuring gash/config.scm.in~%")
         (copy-file "gash/config.scm.in" "gash/config.scm")
         (substitute* "gash/config.scm"
           (("@VERSION@") ,(package-version gash)))
         (format #t "Configuring scripts/gash.in~%")
         (copy-file "scripts/gash.in" "scripts/gash")
         (substitute* "scripts/gash"
           (("@GUILE@") guile)
           (("@MODDIR@") moddir)
           (("@GODIR@") godir))
         (for-each (lambda (scm)
                     (let ((go (string-append (string-drop-right scm 3) "go"))
                           (dir (dirname scm)))
                       (format #t "Compiling ~a~%" scm)
                       (compile-file scm #:output-file go)
                       (format #t "Installing ~a~%" scm)
                       (install-file scm (string-append moddir "/" dir))
                       (format #t "Installing ~a~%" go)
                       (install-file go (string-append godir "/" dir))))
                   (find-files "gash" "\\.scm$"))
         (format #t "Installing scripts/gash~%")
         (install-file "scripts/gash" (string-append out "/bin"))
         (chmod (string-append out "/bin/gash") #o555)
         (symlink (string-append out "/bin/gash")
                  (string-append out "/bin/sh"))
         (symlink (string-append out "/bin/gash")
                  (string-append out "/bin/bash")))))
    (inputs `(("guile" ,%bootstrap-guile)))
    (native-inputs '())))

(define %bootstrap-coreutils&co-without-bash
  (package
    (inherit %bootstrap-coreutils&co)
    (arguments
     (substitute-keyword-arguments (package-arguments %bootstrap-coreutils&co)
       ((#:builder _ #f)
        `(let ((source (assoc-ref %build-inputs "source"))
               (out (assoc-ref %outputs "out")))
           (use-modules (guix build utils))
           (copy-recursively source out)
           (delete-file (string-append out "/bin/sh"))
           (delete-file (string-append out "/bin/bash"))))))
    (inputs
     `(("source" ,%bootstrap-coreutils&co)))))

(define (%bootstrap-coreutils&co? x)
  (eq? %bootstrap-coreutils&co x))

(define %boot0-inputs
  (map (match-lambda
         (("coreutils&co" (? %bootstrap-coreutils&co? value))
          `("coreutils&co" ,%bootstrap-coreutils&co-without-bash))
         (("bash" _)
          `("bash" ,%bootstrap-gash))
         (x x))
       ((@@ (gnu packages commencement) %boot0-inputs))))

(package-with-bootstrap-guile
 (package-with-explicit-inputs (package
                                 (inherit bash-minimal)
                                 (name "bash-boot0"))
                               %boot0-inputs
                               #:guile %bootstrap-guile))

