(* -*- 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 missing_modules =
  let missing =
    List.filter modules_post_4_02 ~f:(fun (_, v) -> version < v)
    |> List.map ~f:fst
  in
    (* For OCaml 4.07-4.09 incl. this solves the problem of being unable to
       generate empty .cmxa files on MSVC by duplicating the Pervasives module
       (and updating its deprecation warning not to refer to this library! *)
    if version < (4, 10) && version >= (4, 7) then
      "Pervasives"::missing
    else
      missing

let all_modules_except_stdlib =
  (modules_in_4_02 @ List.map modules_post_4_02 ~f:fst)
  |> 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 () =
  Printf.ksprintf send {|
(library
   (wrapped false)
   (name stdlib_shims)
   (public_name stdlib-shims)
   (modules %s))

(rule
 (with-stdout-to stdlib.ml
  (echo "\
%s

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