#!/usr/bin/env texlua
-----------------------------------------------------------------------
--         FILE:  mktests
--        USAGE:  ./mktests 
--  DESCRIPTION:  test the behavior of Luaotfload
-- REQUIREMENTS:  Luatex > 0.76, Luaotfload
--       AUTHOR:  Philipp Gesang (Phg), <phg42.2a@gmail.com>
--      VERSION:  2.4
--     MODIFIED:  2013-08-26 09:31:22+0200
-----------------------------------------------------------------------
--
--===================================================================--
--                               NOTE
--             this is a stub, to be completed long-term
--                        suggestions welcome
--===================================================================--


local tests = { }

config = { luaotfload = {
    names_dir     = "names",
    cache_dir     = "fonts",
    index_file    = "luaotfload-names.lua",
    resolver      = "normal",
    update_live   = true, --- suppress db updates
}}

kpse.set_program_name "luatex"

require "lualibs"
require "luaotfload-basics-gen.lua"
require "luaotfload-override.lua"
require "luaotfload-database"

local names = fonts.names

-----------------------------------------------------------------------
--- helper functions
-----------------------------------------------------------------------

local pprint_resolve = function (input, output, result)
  texio.write_nl (string.format ("[%s] “%s” -> “%s”",
                                 result == true and "passed" or "failed",
                                 input,
                                 output))
end

local pprint_result = function (name, failed, total)
  if failed == 0 then
    texio.write_nl (string.format ("[%s] all %d passed", name, total))
  else
    texio.write_nl (string.format ("[%s] %d of %d failed",
                                   name,
                                   failed,
                                   total))
  end
end

local pprint_spec = function (spec)
  return string.format ("%s/%s*%.2fpt",
                        spec.specification,
                        spec.style or "regular",
                        spec.optsize or 0)
end

-----------------------------------------------------------------------
--- font tests
-----------------------------------------------------------------------

--- test sets

local infer_regular_style = {
  --- inferring which one is the correct style for “regular”; can be
  --- obscured by synonyms like “book” etc.
  { "Iwona",                "Iwona-Regular.otf"         }, -- trivial case
  { "DejaVu Serif",         "DejaVuSerif.ttf"           },
  { "DejaVu Sans",          "DejaVuSans.ttf"            },
  { "Adobe Garamond Pro",   "agaramondpro_regular.otf"  },
  { "Garamond Premier Pro", "GaramondPremrPro-Capt.otf" },
  { "CMU Serif",            "cmunrm.otf"                },
  { "CMU Sans Serif",       "cmunss.otf"                },
}

local choose_optical_size = {
  { { name = "Latin Modern Roman", optsize =  0 }, "lmroman5-regular.otf"        },
  { { name = "Latin Modern Roman", optsize = 10 }, "lmroman10-regular.otf"       },
  { { name = "Latin Modern Roman", optsize = 12 }, "lmroman12-regular.otf"       },
  { { name = "Latin Modern Roman", optsize = 42 }, "lmroman17-regular.otf"       },
  { { name = "EB Garamond", optsize =  0 }, "EBGaramond08-Regular.otf"           },
  { { name = "EB Garamond", optsize =  8 }, "EBGaramond08-Regular.otf"           },
  { { name = "EB Garamond", optsize = 12 }, "EBGaramond12-Regular.otf"           },
  { { name = "EB Garamond", optsize = 42 }, "EBGaramond12-Regular.otf"           },
  { { name = "Garamond Premier Pro", optsize =  0 }, "GaramondPremrPro-Capt.otf" },
  { { name = "Garamond Premier Pro", optsize = 10 }, "GaramondPremrPro.otf"      },
  { { name = "Garamond Premier Pro", optsize = 15 }, "GaramondPremrPro-Subh.otf" },
  { { name = "Garamond Premier Pro", optsize = 42 }, "GaramondPremrPro-Disp.otf" },
}

local choose_style = {
  { { name = "DejaVu Sans", style = "regular"    }, "DejaVuSans.ttf"                       },
  { { name = "DejaVu Sans", style = "italic"     }, "DejaVuSans-Oblique.ttf"               },
  { { name = "DejaVu Sans", style = "bold"       }, "DejaVuSans-Bold.ttf"                  },
  { { name = "DejaVu Sans", style = "bolditalic" }, "DejaVuSans-BoldOblique.ttf"           },
  { { name = "Linux Libertine O", style = "regular"    }, "LinLibertine_R.otf"             },
  { { name = "Linux Libertine O", style = "italic"     }, "LinLibertine_RI.otf"            },
  { { name = "Linux Libertine O", style = "bold"       }, "LinLibertine_RB.otf"            },
  { { name = "Linux Libertine O", style = "bolditalic" }, "LinLibertine_RBI.otf"           },
  { { name = "Liberation Serif", style = "regular"    }, "LiberationSerif-Regular.ttf"     },
  { { name = "Liberation Serif", style = "italic"     }, "LiberationSerif-Italic.ttf"      },
  { { name = "Liberation Serif", style = "bold"       }, "LiberationSerif-Bold.ttf"        },
  { { name = "Liberation Serif", style = "bolditalic" }, "LiberationSerif-BoldItalic.ttf"  },
  { { name = "CMU Sans Serif", style = "regular"    }, "cmunss.otf"   }, -- no “regular” but “medium”
  { { name = "CMU Sans Serif", style = "italic"     }, "cmunsi.otf"   }, -- no “italic” but “oblique”
  { { name = "CMU Sans Serif", style = "bold"       }, "cmunsx.otf"   },
  { { name = "CMU Sans Serif", style = "bolditalic" }, "cmunso.otf"   },
}

--- this needs a database built with --formats=+pfa,pfb,afm

local resolve_t1_font = {
  { { name = "URW Gothic L",          style = "regular"    }, "uagk8a.pfb"   },
  { { name = "URW Gothic L",          style = "italic"     }, "uagko8a.pfb"  },
  { { name = "URW Gothic L",          style = "bold"       }, "uagd8a.pfb"   },
  { { name = "URW Gothic L",          style = "bolditalic" }, "uagdo8a.pfb"  },
  { { name = "Century Schoolbook L",  style = "regular"    }, "uncr8a.pfb"   },
  { { name = "Century Schoolbook L",  style = "italic"     }, "uncri8a.pfb"  },
  { { name = "Century Schoolbook L",  style = "bold"       }, "uncb8a.pfb"   },
  { { name = "Century Schoolbook L",  style = "bolditalic" }, "uncbi8a.pfb"  },
  { { name = "Nimbus Roman No9 L",    style = "regular"    }, "utmr8a.pfb"   },
  { { name = "Nimbus Roman No9 L",    style = "italic"     }, "utmri8a.pfb"  },
  { { name = "Nimbus Roman No9 L",    style = "bold"       }, "utmb8a.pfb"   }, --- medium, actually
  { { name = "Nimbus Roman No9 L",    style = "bolditalic" }, "utmbi8a.pfb"  },
}

local font_name_tests = {
  infer_regular_style,
  choose_optical_size,
  choose_style,
  resolve_t1_font,
}

local default_spec = {
  name          = false,
  lookup        = "name",
  specification = false,
  optsize       = 0,
}

local resolve_font_name = function ()
  local failed, total = 0, 0
  local resolve_name = names.resolve
  for nset = 1, #font_name_tests do
    local set = font_name_tests[nset]

    for ntest = 1, #set do
      local test = set[ntest]
      local input, output = test[1], test[2]

      if type (input) == "string" then
        local input_spec = table.copy (default_spec)
        input_spec.name = input
        input_spec.specification = input_spec.lookup .. ":" .. input
        local result = resolve_name (nil, nil, input_spec) == output
        total = total + 1
        if not result then
          failed = failed + 1
        end
        pprint_resolve (input, output, result)

      else
        local input_spec, output = test[1], test[2]
        input_spec.specification = (input_spec.lookup
                                    or default_spec.lookup)
                                .. ":" .. input_spec.name
        input_spec.optsize = input_spec.optsize or default_spec.optsize
        local result = resolve_name (nil, nil, input_spec) == output
        total = total + 1
        if not result then
          failed = failed + 1
        end
        pprint_resolve (pprint_spec (input_spec), output, result)
      end

    end
  end
  return failed, total
end

tests ["resolve_font_name"] = resolve_font_name

-----------------------------------------------------------------------
--- runner
-----------------------------------------------------------------------

local main = function ()
  local failed, total = 0, 0
  for name, test in next, tests do
    texio.write_nl ("[" .. name .. "]")
    local newfailed, newtotal = test ()
    total  = total + 1
    pprint_result (name, newfailed, newtotal)
    failed = failed + newfailed
    total  = total  + newtotal
  end

  if failed == 0 then
    texio.write_nl (string.format ("[report] all %d tests passed.", total))
  else
    texio.write_nl (string.format ("[report] %d of %d tests failed (%d %%).",
                                   failed,
                                   total,
                                   failed / total * 100))
  end
  texio.write_nl ""
  os.exit (0)
end

return main ()