(* -*- tuareg -*- *)

open StdLabels
open Jbuild_plugin.V1

let version = Scanf.sscanf ocaml_version "%u.%u" (fun a b -> (a, b))

let modules_in_4_02 =
  [ "Arg"
  ; "Array"
  ; "ArrayLabels"
  ; "Buffer"
  ; "Bytes"
  ; "BytesLabels"
  ; "Callback"
  ; "Char"
  ; "Complex"
  ; "Digest"
  ; "Filename"
  ; "Format"
  ; "Gc"
  ; "Genlex"
  ; "Hashtbl"
  ; "Int32"
  ; "Int64"
  ; "Lazy"
  ; "Lexing"
  ; "List"
  ; "ListLabels"
  ; "Map"
  ; "Marshal"
  ; "MoreLabels"
  ; "Nativeint"
  ; "Obj"
  ; "Oo"
  ; "Parsing"
  ; "Pervasives"
  ; "Printexc"
  ; "Printf"
  ; "Queue"
  ; "Random"
  ; "Scanf"
  ; "Set"
  ; "Stack"
  ; "StdLabels"
  ; "Stream"
  ; "String"
  ; "StringLabels"
  ; "Sys"
  ; "Weak"
  ]

let modules_post_4_02 =
  [ "Float", (4, 07)
  ; "Seq", (4, 07)
  ; "Stdlib", (4, 07)
  ; "Uchar", (4, 03)
  ]

let available_modules =
  modules_in_4_02 @
  (List.filter modules_post_4_02 ~f:(fun (m, v) ->
       version >= v)
   |> List.map ~f:fst)

let all_modules_except_stdlib =
  available_modules
  |> List.filter ~f:((<>) "Stdlib")
  |> List.sort ~cmp:String.compare

let longest_module_name =
  List.fold_left all_modules_except_stdlib ~init:0
    ~f:(fun acc m -> max acc (String.length m))

let stdlib_rule =
  Printf.sprintf {|
(rule
 (with-stdout-to stdlib.ml
  (echo "\
%s

include Pervasives
")))
|}
    (List.map all_modules_except_stdlib
       ~f:(fun m -> Printf.sprintf "module %-*s = %s" longest_module_name m m)
     |> String.concat ~sep:"\n")

let () =
  Printf.ksprintf send {|
(library
 (wrapped false)
 (name stdlib_shims)
 (public_name stdlib-shims))
%s
|}
    (if version >= (4, 07) then "" else stdlib_rule)
