"""Reproduce every figure of Bishop (2006), Chapters 1 to 14, and run the checks.

usage:
    python3 make_all.py             # all figures, then all numerical checks
    python3 make_all.py --figures   # figures only
    python3 make_all.py --checks    # numerical checks only
    python3 make_all.py --out DIR   # write the figures to DIR instead of ../img

Each chapter module can also be run on its own, e.g.
    python3 ch09_mixture_em.py --list
    python3 ch09_mixture_em.py --fig 9.1 9.8
"""
import os

# Small dense matrices: many BLAS threads slow numpy down badly on busy machines.
for _v in ("OPENBLAS_NUM_THREADS", "MKL_NUM_THREADS", "OMP_NUM_THREADS"):
    os.environ.setdefault(_v, "1")

import argparse
import importlib
import subprocess
import sys
import time

MODULES = ["ch01_introduction", "ch02_probability_distributions", "ch03_linear_regression", "ch04_linear_classification",
           "ch05_neural_networks", "ch06_kernel_methods", "ch07_sparse_kernel_machines", "ch08_graphical_models", "ch09_mixture_em", "ch10_variational_inference", "ch10_local_variational_ep",
           "ch11_sampling", "ch12_continuous_latent", "ch13_sequential_data", "ch14_combining_models"]
CHECKS = ["checks_ch01", "checks_ch02", "checks_ch03", "checks_ch04", "checks_ch05", "checks_ch06", "checks_ch07", "checks_ch08", "checks_ch09", "checks_ch10a", "checks_ch10b", "checks_ch11", "checks_ch12", "checks_ch13", "checks_ch14"]
CHAPTER = {"ch01": 1, "ch02": 2, "ch03": 3, "ch04": 4, "ch05": 5, "ch06": 6, "ch07": 7, "ch08": 8, "ch09": 9, "ch10": 10, "ch11": 11, "ch12": 12, "ch13": 13, "ch14": 14}


def main():
    p = argparse.ArgumentParser(description=__doc__.split("\n")[0])
    p.add_argument("--figures", action="store_true", help="only make the figures")
    p.add_argument("--checks", action="store_true", help="only run the numerical checks")
    p.add_argument("--out", default=None, help="output folder for the figures (default ../img)")
    a = p.parse_args()
    do_fig = a.figures or not a.checks
    do_chk = a.checks or not a.figures
    failed = []
    t0 = time.time()
    if do_fig:
        for name in MODULES:
            print("=" * 8, name)
            mod = importlib.import_module(name)
            args = [] if a.out is None else ["--out", a.out]
            try:
                import common
                common.run(mod.FIGURES, CHAPTER[name[:4]], args)
            except Exception as e:  # keep going, report at the end
                print("  FAILED:", e)
                failed.append(name)
    if do_chk:
        for name in CHECKS:
            print("=" * 8, name)
            r = subprocess.run([sys.executable, name + ".py"])
            if r.returncode != 0:
                failed.append(name)
    print("\nfinished in %.0f s" % (time.time() - t0))
    if failed:
        print("problems in:", ", ".join(failed))
        sys.exit(1)


if __name__ == "__main__":
    main()
