type descr = {
  interface_only : string list;
  interface : string list;
  internal : string list;
}

let server = {
  interface_only = [
    "eliom_content_sigs";
    "eliom_form_sigs";
    "eliom_parameter_sigs";
    "eliom_registration_sigs";
    "eliom_service_sigs";
    "eliom_shared_sigs";
  ];
  interface = [
    "eliom_bus";
    "eliom_client_value";
    "eliom_syntax";
    "eliom_client";
    "eliom_comet";
    "eliom_common";
    "eliom_config";
    "eliom_content";
    "eliom_extension";
    "eliom_lib";
    "eliom_mkreg";
    "eliom_notif";
    "eliom_parameter";
    "eliom_react";
    "eliom_shared";
    "eliom_cscache";
    "eliom_reference";
    "eliom_registration";
    "eliom_request_info";
    "eliom_service";
    "eliom_state";
    "eliom_tools";
    "eliom_types";
    "eliom_uri";
    "eliom_wrap";
  ];
  internal = [
    "eliom_comet_base";
    "eliom_common_base";
    "eliom_runtime";
    "eliom_content_";
    "eliom_content_core";
    "eliom_cookies_base";
    "eliom_error_pages";
    "eliom_form";
    "eliom_lazy";
    "eliom_lib_base";
    "eliom_parameter_base";
    "eliom_process";
    "eliom_service_base";
    "eliom_route";
    "eliom_route_base";
    "eliom_shared_content";
    "eliom_types_base";
    "eliom_client_main";
    "eliommod";
    "eliommod_cli";
    "eliommod_cookies";
    "eliommod_datasess";
    "eliommod_gc";
    "eliommod_pagegen";
    "eliommod_parameters";
    "eliommod_persess";
    "eliommod_sersess";
    "eliommod_sessadmin";
    "eliommod_sessexpl";
    "eliommod_sessiongroups";
    "eliommod_timeouts";
  ]
}
let client = {
  interface_only = [
    "eliom_content_sigs";
    "eliom_form_sigs";
    "eliom_parameter_sigs";
    "eliom_registration_sigs";
    "eliom_service_sigs";
    "eliom_shared_sigs";
  ];
  interface = [
    "eliom_bus";
    "eliom_client_value";
    "eliom_client_core";
    "eliom_client";
    "eliom_comet";
    "eliom_config";
    "eliom_content";
    "eliom_content_core";
    "eliom_lazy";
    "eliom_lib";
    "eliom_parameter";
    "eliom_react";
    "eliom_shared";
    "eliom_cscache";
    "eliom_registration";
    "eliom_service";
    "eliom_tools";
    "eliom_types";
    "eliom_unwrap";
    "eliom_uri";
  ];
  internal = [
    "eliom_comet_base";
    "eliom_common";
    "eliom_common_base";
    "eliom_runtime";
    "eliom_content_";
    "eliom_cookies_base";
    "eliom_form";
    "eliom_lib_base";
    "eliom_parameter_base";
    "eliom_process";
    "eliom_request";
    "eliom_request_info";
    "eliom_service_base";
    "eliom_route";
    "eliom_route_base";
    "eliom_shared_content";
    "eliom_types_base";
    "eliommod_cookies";
    "eliommod_dom";
    "eliommod_parameters";
  ];
}

let server_ext = {
  interface_only = [];
  interface = [
    "atom_feed";
    "eliom_atom";
    "eliom_openid";
    "eliom_s2s"];
  internal = []
}

let ocamlbuild = {
  interface_only = [];
  interface = [ "ocamlbuild_eliom" ];
  internal = []

}

let ppx = {
  interface_only = [];
  interface = [ "ppx_eliom" ; "ppx_eliom_client" ; "ppx_eliom_type" ; "ppx_eliom_server" ];
  internal = [ "ppx_eliom_utils" ];
}


let (-.-) name ext = name ^ "." ^ ext
let exts el sl =
  List.flatten (
    List.map (fun ext ->
        List.map (fun name ->
            name -.- ext) sl) el)

let list_to_file filename list =
  let oc = open_out filename in
  List.iter (fun s ->
      output_string oc s;
      output_char oc '\n';
    ) list;
  close_out oc;;

let client_mllib =
  client.interface @ client.internal

let client_extra =
  exts ["cmi"] (client.interface_only @ client.interface)

let client_api =
  client.interface_only @ client.interface

let server_mllib =
  server.interface @ server.internal

let server_extra =
  exts ["cmi"] (server.interface_only @ server.interface) @
  exts ["cmx"] (server.interface @ server.internal)

let server_api =
  server.interface_only @ server.interface

let server_ext_mllib = server_ext.interface @ server_ext.internal
let server_ext_extra =
  exts ["cmi"] (server_ext.interface_only @ server_ext.interface) @
  exts ["cmx"] (server_ext.interface @ server_ext.internal)

let ocamlbuild_mllib = ocamlbuild.interface @ ocamlbuild.internal
let ocamlbuild_extra =
  exts ["cmi"] (ocamlbuild.interface_only @ ocamlbuild.interface) @
  exts ["cmx"] (ocamlbuild.interface @ ocamlbuild.internal)
let ocamlbuild_api = ocamlbuild.interface_only @ ocamlbuild.interface

let ppx_mllib = ppx.interface @ ppx.internal
let ppx_extra =
  exts ["cmi"] ppx.interface @
  exts ["cmx"] (ppx.interface @ ppx.internal)
let ppx_api = ppx.interface


let templates_dir = "pkg/distillery"
let templates = Array.to_list (Sys.readdir templates_dir)
let templates_files =
  List.map (fun name ->
    name, Array.to_list (Sys.readdir (templates_dir^"/"^name))) templates
