/*
 * Copyright © 2025  Skef Iterum
 *
 *  This is part of HarfBuzz, a text shaping library.
 *
 * Permission is hereby granted, without written agreement and without
 * license or royalty fees, to use, copy, modify, and distribute this
 * software and its documentation for any purpose, provided that the
 * above copyright notice and the following two paragraphs appear in
 * all copies of this software.
 *
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 *
 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 */

#include "hb-test.h"

#include <hb.h>
#include <hb-ot.h>
#include <hb-subset.h>

#ifndef HB_NO_SUBSET_DEPEND

/*
 * ============================================================================
 * DEPEND TEST DEVELOPMENT NOTES (TEMPORARY - REMOVE WHEN COMPLETE)
 * ============================================================================
 *
 * TESTING PHILOSOPHY (Option B: "Double Duty")
 * ----------------------------------------------
 * We use a "double duty" approach where tests serve multiple purposes:
 * 1. Basic substitution tests verify the fundamental substitution types work
 * 2. Contextual format tests verify BOTH:
 *    - The contextual format parsing/traversal works
 *    - Recursion correctly invokes nested lookups
 *    - The invoked basic substitution type produces correct dependencies
 *
 * This reduces redundancy while maximizing coverage. Instead of separate tests
 * for "SingleSubst works" and "ContextSubst Format 2 works", we test
 * "ContextSubst Format 2 correctly invokes SingleSubst".
 *
 * COVERAGE REQUIREMENTS
 * ---------------------
 * Basic GSUB substitution types:
 *   ✓ SingleSubst - covered via contextual recursion tests
 *   ✓ MultipleSubst - covered via contextual recursion tests
 *   ✓ AlternateSubst - standalone test (has special AlternateSet behavior)
 *   ✓ LigatureSubst - standalone test (has special ligature_set tracking)
 *   ✓ ReverseChainSingleSubst - standalone test (special type 8)
 *
 * Contextual/Chaining substitution formats:
 *   ✓ ContextSubst Format 1 (glyph-based with SubRuleSets)
 *   ✓ ContextSubst Format 2 (class-based with SubClassSets)
 *   ✓ ContextSubst Format 3 (coverage-based inline)
 *   ✓ ChainContextSubst Format 1 (glyph-based with backtrack/lookahead)
 *   ✓ ChainContextSubst Format 2 (class-based with backtrack/lookahead)
 *   ✓ ChainContextSubst Format 3 (coverage-based with backtrack/lookahead)
 *
 * Special features:
 *   ✓ ExtensionSubst (Type 7) - implicitly tested (174 instances in NotoNastaliqUrdu)
 *   ✓ Feature tagging - verify layout_tag propagates through recursion
 *   ✓ Ligature set tracking - verify ligature_set is assigned for alternates
 *   ✓ Contextual filtering - verify glyphs unreachable from context are excluded
 *
 * IMPLICIT vs EXPLICIT TESTING
 * -----------------------------
 * Explicit: We have a test assertion that verifies a specific dependency
 *           from a known lookup format. If the format is broken, test fails.
 *
 * Implicit: The code path executes (font has those lookups), but we don't
 *           assert a specific dependency from that format. If format is broken,
 *           tests might still pass.
 *
 * We prefer EXPLICIT tests for all major formats. Implicit is acceptable only
 * for ExtensionSubst (which is transparent) and edge cases.
 *
 * HOW TO FIND TEST CASES
 * ----------------------
 * 1. Extract GSUB table from font:
 *    ttx -q -t GSUB test/api/fonts/FontName.ttf -o /tmp/font-gsub.ttx
 *
 * 2. Find contextual lookups of desired format:
 *    grep -n "ContextSubst Format=\"2\"" /tmp/font-gsub.ttx
 *
 * 3. Look at the lookup structure (around the line number from step 2):
 *    sed -n 'START,END p' /tmp/font-gsub.ttx
 *    - Note the Coverage (which glyphs this applies to)
 *    - Note the ClassDef (for Format 2) or inline coverages (for Format 3)
 *    - Find SubstLookupRecord entries showing which lookups are invoked
 *
 * 4. Check what the invoked lookup does:
 *    grep -A15 '<Lookup index="N">' /tmp/font-gsub.ttx
 *
 * 5. Find glyph IDs:
 *    ttx -q -t GlyphOrder test/api/fonts/FontName.ttf -o - 2>&1 | grep "GlyphName"
 *
 * 6. Verify the dependency exists (test in isolation first if uncertain)
 *
 * CRITERIA FOR GOOD TEST CASES
 * -----------------------------
 * 1. Simple: Prefer lookups with small coverage, simple contexts
 * 2. Clear: The glyph→glyph dependency should be unambiguous
 * 3. Direct: Avoid deeply nested recursion if possible
 * 4. Documented: Comments should explain:
 *    - Which lookup(s) are involved
 *    - What format is being tested
 *    - What the context is (if applicable)
 *    - What basic substitution type is invoked
 *
 * FIND_DEPENDENCY HELPER
 * ----------------------
 * The find_dependency() helper has special IN-OUT parameter behavior:
 *
 * layout_tag as filter (IN):
 *   If *out_layout_tag != HB_TAG_NONE, only matches that specific layout tag
 *   Example: layout_tag = HB_TAG('c','c','m','p');
 *            find_dependency(..., &layout_tag, NULL);
 *
 * layout_tag as output (OUT):
 *   If *out_layout_tag == HB_TAG_NONE, returns the layout_tag found
 *   Example: layout_tag = HB_TAG_NONE;
 *            find_dependency(..., &layout_tag, &ligature_set);
 *            // layout_tag now contains the tag of the dependency found
 *
 * This dual mode reduces code duplication for common patterns.
 *
 * REMAINING TESTS TO ADD
 * ----------------------
 * The depend API extracts dependencies from these tables:
 *   ✓ GSUB - glyph substitution (all formats and critical edge cases tested)
 *       - Multiple subtables per lookup (regression test for Bug #1)
 *       - Same lookup called multiple times in context (regression test for Bug #2)
 *   ✓ cmap - character mapping (COMPLETE)
 *       - Nominal glyph mappings: NOT stored as dependencies (Unicode → glyph
 *         is not a glyph→glyph relationship). Stored in separate nominal_glyphs map.
 *       - Unicode Variation Sequences (UVS): Only NonDefault UVS creates dependencies
 *         (nominal_glyph(U) → variant_glyph(U+S) with layout_tag=S)
 *       - Default UVS entries do NOT create dependencies
 *       - Tested with base.ttf: U+904D + 0xE01E5 → variant glyph
 *   ✓ glyf - composite glyphs (COMPLETE)
 *       - Component references in TrueType composite glyphs
 *       - Tested: Afghani (202) → three components in NotoNastaliqUrdu
 *       - Tagged with HB_TAG('g','l','y','f')
 *   ✓ COLR - color layering (COMPLETE)
 *       - COLRv0: Base glyph → layer glyphs (tested with COLRv0.extents.ttf)
 *       - COLRv1: Paint graph dependencies (tested with test_glyphs-glyf_colr_1.ttf)
 *       - Tagged with HB_TAG('C','O','L','R')
 *       - Fixed: Added guard to prevent v0-only fonts from accessing v1 data structures
 *   ✓ MATH - mathematical variants (COMPLETE)
 *       - Vertical/horizontal variants (tested with arrowup variants)
 *       - Size variants (uni2191_size2, etc.)
 *       - Glyph assembly parts (bottom, vertical)
 *       - Tested with MathTestFontFull.otf
 *       - Tagged with HB_TAG('M','A','T','H')
 *
 * SUMMARY OF TEST COVERAGE:
 * ---------------------------
 * ✓ GSUB: Complete - all 8 substitution types, 6 contextual formats, and edge cases:
 *     - Lookups with multiple subtables (first subtable may not contain target rule)
 *     - Contextual rules calling same lookup at multiple sequence positions
 * ✓ cmap: Complete - NonDefault UVS dependencies tested (base.ttf)
 * ✓ glyf: Complete - composite glyph dependencies tested
 * ✓ MATH: Complete - size variants and glyph assembly tested
 * ✓ COLR: Complete - both v0 layer dependencies and v1 Paint graph tested
 *
 * ADDING NEW TESTS
 * ----------------
 * When adding tests for new tables:
 * 1. Follow the same "double duty" philosophy where applicable
 * 2. Document format coverage in comments
 * 3. Test both basic types AND contextual/recursive mechanisms (if applicable)
 * 4. Include negative tests where filtering or exclusion is important
 * 5. Verify feature tagging where relevant (table_tag should be correct)
 * 6. Update this comment block with new insights
 *
 * TEST FONTS
 * ----------
 * - SourceSansPro-Regular.otf: Basic Latin font with common GSUB features
 *   Used for: AlternateSubst, LigatureSubst, ChainContextSubst Format 3
 *
 * - NotoSans-Bold.ttf: Fast font with comprehensive GSUB formats (0.01-0.02s init)
 *   Used for: glyf composite glyphs, ContextSubst Format 1
 *   Has: ContextSubst Format 1/2, ChainContextSubst Format 1/2/3
 *
 * - NotoNastaliqUrdu-Regular.ttf: Complex Arabic Nastaliq font (4+ seconds init)
 *   Used for: Contextual filtering negative test (issue #3397)
 *   TODO: Create minimal subset for remaining Format 2 tests
 *   Has: 174 ExtensionSubst lookups, 28 ChainContextSubst Format 2
 *
 * - Qahiri-Regular.ttf: Arabic font with various contextual formats
 *   Used for: ReverseChainSingleSubst, ContextSubst Format 3,
 *            ChainContextSubst Format 1
 *
 * KEY INSIGHTS FROM DEVELOPMENT
 * ------------------------------
 * 1. ExtensionSubst (Type 7) is transparent - it wraps other lookup types.
 *    No need for explicit tests; if wrapped types work, extension works.
 *
 * 2. ChainContextSubst Format 2 is the most complex:
 *    - Has BacktrackClassDef, InputClassDef, LookAheadClassDef
 *    - Rules reference classes, not glyphs directly
 *    - Need to map glyphs → classes → rules to find what happens
 *
 * 3. Contextual filtering (issue #3397) is crucial:
 *    - When context C invokes lookup L, only glyphs reachable from C's
 *      input pattern should get dependencies from L
 *    - Test both positive (dependency exists) and negative (doesn't exist)
 *
 * 4. Feature tagging propagation:
 *    - When feature F's lookup invokes another lookup via context,
 *      the resulting dependencies should be tagged with F
 *    - Important for subsetting - tells which glyphs are needed for which features
 *
 * ============================================================================
 */

/*
 * Utility function to search for a specific dependency.
 * Loops through all dependency entries for source_glyph and returns TRUE
 * if a dependency on target_glyph with the expected table_tag is found.
 *
 * If out_layout_tag is non-NULL and *out_layout_tag is not HB_TAG_NONE,
 * only matches entries with that specific layout_tag (in-out parameter).
 * Otherwise returns the layout_tag of the match found (out parameter).
 *
 * If found, optionally returns the ligature_set via out parameter.
 */
static hb_bool_t
find_dependency (hb_subset_depend_t *depend,
                 hb_codepoint_t source_glyph,
                 hb_codepoint_t target_glyph,
                 hb_tag_t expected_table_tag,
                 hb_tag_t *out_layout_tag,          /* IN-OUT (optional) */
                 hb_codepoint_t *out_ligature_set)  /* OUT (optional) */
{
  hb_tag_t filter_layout_tag = (out_layout_tag && *out_layout_tag != HB_TAG_NONE)
                                ? *out_layout_tag : HB_TAG_NONE;

  unsigned int total = hb_subset_depend_lookup_glyph (depend, source_glyph, 0, NULL, NULL);
  for (unsigned int index = 0; index < total; index++)
  {
    hb_subset_depend_entry_t entry;
    unsigned int count = 1;
    hb_subset_depend_lookup_glyph (depend, source_glyph, index, &count, &entry);

    if (entry.table_tag == expected_table_tag && entry.dependent == target_glyph)
    {
      /* If filtering by layout_tag, check if it matches */
      if (filter_layout_tag != HB_TAG_NONE && entry.layout_tag != filter_layout_tag)
        continue;

      if (out_layout_tag)
        *out_layout_tag = entry.layout_tag;
      if (out_ligature_set)
        *out_ligature_set = entry.ligature_set_index;
      return TRUE;
    }
  }

  return FALSE;
}


/* Test glyf (composite glyph) dependency extraction */
static void
test_depend_glyf (void)
{
  /* NotoSans-Bold.ttf has composite glyphs */
  hb_face_t *face = hb_test_open_font_file ("fonts/NotoSans-Bold.ttf");
  hb_subset_depend_t *depend = hb_subset_depend_from_face_or_fail (face);
  g_assert_nonnull (depend);

  /* Composite glyph "Aacute" (131) is composed of two components:
   * - A (36)
   * - acute (118)
   * The composite glyph depends on all its components. */

  g_test_message ("Testing glyf composite: Aacute (131) → A (36)");
  g_assert_true (find_dependency (depend, 131, 36, HB_TAG('g','l','y','f'),
                                  NULL, NULL));

  g_test_message ("Testing glyf composite: Aacute (131) → acute (118)");
  g_assert_true (find_dependency (depend, 131, 118, HB_TAG('g','l','y','f'),
                                  NULL, NULL));

  hb_subset_depend_destroy (depend);
  hb_face_destroy (face);
}

/* Test CFF SEAC (Standard Encoding Accented Character) dependency extraction */
static void
test_depend_cff (void)
{
  /* cff1_seac.C0.otf has a SEAC composite glyph */
  hb_face_t *face = hb_test_open_font_file ("fonts/cff1_seac.C0.otf");
  hb_subset_depend_t *depend = hb_subset_depend_from_face_or_fail (face);
  g_assert_nonnull (depend);

  /* Glyph 2 is a SEAC composite defined as base (glyph 1) + accent (glyph 3).
   * The composite glyph depends on both components. */

  g_test_message ("Testing CFF SEAC composite: glyph 2 → base (1)");
  g_assert_true (find_dependency (depend, 2, 1, HB_TAG('C','F','F',' '),
                                  NULL, NULL));

  g_test_message ("Testing CFF SEAC composite: glyph 2 → accent (3)");
  g_assert_true (find_dependency (depend, 2, 3, HB_TAG('C','F','F',' '),
                                  NULL, NULL));

  hb_subset_depend_destroy (depend);
  hb_face_destroy (face);
}

/* Test COLR (color layering) dependency extraction */
static void
test_depend_colr (void)
{
  /* COLRv0: base glyph with layer glyphs */
  hb_face_t *face = hb_test_open_font_file ("fonts/COLRv0.extents.ttf");
  hb_subset_depend_t *depend = hb_subset_depend_from_face_or_fail (face);
  g_assert_nonnull (depend);

  g_test_message ("Testing COLRv0: glyph00013 (13) → glyph00010 (10)");
  g_assert_true (find_dependency (depend, 13, 10, HB_TAG('C','O','L','R'), NULL, NULL));

  hb_subset_depend_destroy (depend);
  hb_face_destroy (face);

  /* COLRv1: Paint graph dependencies */
  face = hb_test_open_font_file ("fonts/test_glyphs-glyf_colr_1.ttf");
  depend = hb_subset_depend_from_face_or_fail (face);
  g_assert_nonnull (depend);

  g_test_message ("Testing COLRv1 v0 layer: glyph 168 → glyph 176");
  g_assert_true (find_dependency (depend, 168, 176, HB_TAG('C','O','L','R'), NULL, NULL));

  g_test_message ("Testing COLRv1 PaintGlyph Format 10: glyph 12 → glyph 176");
  g_assert_true (find_dependency (depend, 12, 176, HB_TAG('C','O','L','R'), NULL, NULL));

  g_test_message ("Testing COLRv1 PaintGlyph self-reference filtered: glyph 8 should NOT depend on itself");
  g_assert_false (find_dependency (depend, 8, 8, HB_TAG('C','O','L','R'), NULL, NULL));

  hb_subset_depend_destroy (depend);
  hb_face_destroy (face);
}

/* Test MATH (mathematical variants) dependency extraction */
static void
test_depend_math (void)
{
  /* MathTestFontFull.otf has full MATH table with variants and assemblies */
  hb_face_t *face = hb_test_open_font_file ("fonts/MathTestFontFull.otf");
  hb_subset_depend_t *depend = hb_subset_depend_from_face_or_fail (face);
  g_assert_nonnull (depend);

  /* Base glyph "arrowup" (31) has:
   * - Size variants: uni2191_size2 (68), uni2191_size3 (69), etc.
   * - Glyph assembly parts: bottom (62), vertical (64)
   */

  g_test_message ("Testing MATH size variant: arrowup (31) → uni2191_size2 (68)");
  g_assert_true (find_dependency (depend, 31, 68, HB_TAG('M','A','T','H'),
                                  NULL, NULL));

  g_test_message ("Testing MATH assembly part: arrowup (31) → bottom (62)");
  g_assert_true (find_dependency (depend, 31, 62, HB_TAG('M','A','T','H'),
                                  NULL, NULL));

  g_test_message ("Testing MATH assembly part: arrowup (31) → vertical (64)");
  g_assert_true (find_dependency (depend, 31, 64, HB_TAG('M','A','T','H'),
                                  NULL, NULL));

  hb_subset_depend_destroy (depend);
  hb_face_destroy (face);
}

/* Test GSUB dependency extraction for all substitution formats */
static void
test_depend_gsub_formats (void)
{
  hb_tag_t layout_tag = HB_TAG_NONE;
  hb_codepoint_t ligature_set;

  /* ===== BASIC SUBSTITUTION TYPES ===== */

  /* SourceSansPro-Regular.otf */
  hb_face_t *face_source = hb_test_open_font_file ("fonts/SourceSansPro-Regular.otf");
  hb_subset_depend_t *depend_source = hb_subset_depend_from_face_or_fail (face_source);
  g_assert_nonnull (depend_source);

  /* AlternateSubst: A → A.sc (tests AlternateSet with multiple alternates) */
  g_test_message ("Testing AlternateSubst: A (2) → A.sc (1217)");
  g_assert_true (find_dependency (depend_source, 2, 1217, HB_OT_TAG_GSUB,
                                  NULL, NULL));

  /* LigatureSubst: multiple glyphs to one (tests Ligature and LigatureSet) */
  g_test_message ("Testing LigatureSubst: uni0302 (1829) → uni03020300 (1910)");
  g_assert_true (find_dependency (depend_source, 1829, 1910, HB_OT_TAG_GSUB,
                                  &layout_tag, &ligature_set));
  g_test_message ("  ligature_set = %u", ligature_set);

  /* Verify ligature set contains both components (1823, 1829) */
  g_assert_cmpuint (HB_CODEPOINT_INVALID, !=, ligature_set);
  hb_set_t *lig_set_source = hb_set_create ();
  g_assert_true (hb_subset_depend_lookup_set (depend_source, ligature_set, lig_set_source));
  g_assert_true (hb_set_has (lig_set_source, 1823));  /* First ligature component */
  g_assert_true (hb_set_has (lig_set_source, 1829));  /* Second ligature component (uni0302) */
  hb_set_destroy (lig_set_source);

  hb_subset_depend_destroy (depend_source);
  hb_face_destroy (face_source);

  /* Qahiri-Regular.ttf */
  hb_face_t *face_qahiri = hb_test_open_font_file ("fonts/Qahiri-Regular.ttf");
  hb_subset_depend_t *depend_qahiri = hb_subset_depend_from_face_or_fail (face_qahiri);
  g_assert_nonnull (depend_qahiri);

  /* ReverseChainSingleSubst */
  g_test_message ("Testing ReverseChainSingleSubst: glyph00047 (47) → glyph00463 (463)");
  g_assert_true (find_dependency (depend_qahiri, 47, 463, HB_OT_TAG_GSUB,
                                  NULL, NULL));

  /* ===== CONTEXTUAL SUBSTITUTION FORMATS (with recursion) ===== */

  /* ContextSubst Format 3 → SingleSubst
   * Lookup 31: Format 3 context invokes Lookup 1 (SingleSubst) */
  g_test_message ("Testing ContextSubst Format 3 → SingleSubst: glyph00053 (53) → glyph00052 (52)");
  g_assert_true (find_dependency (depend_qahiri, 53, 52, HB_OT_TAG_GSUB,
                                  NULL, NULL));

  /* ChainContextSubst Format 1 → SingleSubst
   * Lookup 11: Format 1 chain context invokes Lookup 2 (SingleSubst) twice */
  g_test_message ("Testing ChainContextSubst Format 1 → SingleSubst: glyph00159 (159) → glyph00162 (162)");
  g_assert_true (find_dependency (depend_qahiri, 159, 162, HB_OT_TAG_GSUB,
                                  NULL, NULL));

  /* Verify second call to same lookup (Bug regression test)
   * Same Lookup 11 calls Lookup 2 AGAIN at SequenceIndex=1 for glyph 154
   * This catches Bug #2: lookups_seen blocking repeated lookup calls */
  g_test_message ("Testing same lookup called twice (Bug regression): glyph00154 (154) → glyph00155 (155)");
  g_assert_true (find_dependency (depend_qahiri, 154, 155, HB_OT_TAG_GSUB,
                                  NULL, NULL));

  /* Lookup 28: Multiple subtables with nested lookup calls (Bug regression tests)
   * This lookup has 3 subtables:
   *   - Subtable 0: Has 4 inputs, SubstCount=0 (no nested lookups)
   *   - Subtable 1: Has 2 inputs, calls Lookup 3 twice
   *   - Subtable 2: Additional rules
   * Tests both bugs:
   *   - Bug #1: Must process all subtables (not stop after first)
   *   - Bug #2: Must allow same lookup called multiple times */

  /* Lookup 28 Subtable 1 calls Lookup 3 at SequenceIndex=0 for glyph 47 */
  g_test_message ("Testing multiple subtables (Bug regression): glyph00047 (47) → glyph00051 (51) via Lookup 28→3");
  g_assert_true (find_dependency (depend_qahiri, 47, 51, HB_OT_TAG_GSUB,
                                  NULL, NULL));

  /* Lookup 28 Subtable 1 calls Lookup 3 AGAIN at SequenceIndex=1 for glyph 212 */
  g_test_message ("Testing same lookup twice in context (Bug regression): glyph00212 (212) → glyph00220 (220) via Lookup 28→3");
  g_assert_true (find_dependency (depend_qahiri, 212, 220, HB_OT_TAG_GSUB,
                                  NULL, NULL));

  hb_subset_depend_destroy (depend_qahiri);
  hb_face_destroy (face_qahiri);

  /* NotoSans-Bold.ttf has ContextSubst Format 1, Format 2, and ChainContextSubst Format 2 */
  hb_face_t *face_notosans = hb_test_open_font_file ("fonts/NotoSans-Bold.ttf");
  hb_subset_depend_t *depend_notosans = hb_subset_depend_from_face_or_fail (face_notosans);
  g_assert_nonnull (depend_notosans);

  /* ContextSubst Format 1 → LigatureSubst
   * Lookup 88: Format 1 context invokes Lookup 106 (LigatureSubst)
   * When uni092C is followed by uni094D, creates ligature baprehalfdeva */
  g_test_message ("Testing ContextSubst Format 1 → LigatureSubst: uni092C (3893) → baprehalfdeva (4156)");
  layout_tag = HB_TAG('h','a','l','f');
  g_assert_true (find_dependency (depend_notosans, 3893, 4156, HB_OT_TAG_GSUB,
                                  &layout_tag, &ligature_set));

  /* REGRESSION TEST: Sequential accumulation for intermediate glyphs
   *
   * Test case: NotoSans-Bold Devanagari contextual substitution
   *   - Glyph 3948: uni093C (nukta combining mark)
   *   - Glyph 3969: uni0944 (vowel sign)
   *   - Glyph 4017: rrvocalicvowelsignnuktaleftdeva (ligature output)
   *
   * Contextual rule flow:
   *   1. Match pattern: [nukta-consonant] + [vowel-sign-uni0944]
   *   2. Apply Lookup A at position 0: Decompose nukta-consonant → base + uni093C
   *   3. Apply Lookup B at position 1: Ligate uni093C + uni0944 → glyph 4017
   *
   * The bug (before fix):
   *   - Lookup B only saw glyphs from input coverage
   *   - uni093C (3948) is an intermediate output, not in original coverage
   *   - Edge 3948 → 4017 was MISSING from dependency graph
   *
   * The fix (sequential accumulation):
   *   - Process lookups in order, accumulating outputs
   *   - Lookup B now sees accumulated glyphs including 3948
   *   - Edge 3948 → 4017 is correctly recorded
   *
   * This edge is critical: if a user subsets glyph 3948, they need 4017 too. */
  g_test_message ("Testing sequential accumulation: uni093C (3948) → rrvocalicvowelsignnuktaleftdeva (4017)");
  layout_tag = HB_TAG('b','l','w','s');
  g_assert_true (find_dependency (depend_notosans, 3948, 4017, HB_OT_TAG_GSUB,
                                  &layout_tag, &ligature_set));
  g_test_message ("  ligature_set = %u", ligature_set);

  /* Verify ligature set contains the other component glyph (3969) */
  g_assert_cmpuint (HB_CODEPOINT_INVALID, !=, ligature_set);
  hb_set_t *lig_set = hb_set_create ();
  g_assert_true (hb_subset_depend_lookup_set (depend_notosans, ligature_set, lig_set));
  g_assert_true (hb_set_has (lig_set, 3969));  /* uni0944 is the other ligature component */
  hb_set_destroy (lig_set);

  hb_subset_depend_destroy (depend_notosans);
  hb_face_destroy (face_notosans);

  /* ContextFormat2-Depend-Test.ttf - Test font for contextual substitution formats
   * Created from NotoNastaliqUrdu-Regular.ttf (486KB → 85KB, 83% reduction)
   * - GSUB table minimized to 6 lookups needed for tests
   * - All glyph outline data removed (only table structures kept)
   * Test lookups:
   *   - Lookup 9, 10: ContextSubst for contextual filtering test
   *   - Lookup 17, 20: ContextSubst Format 2 → MultipleSubst test
   *   - Lookup 25, 119: ChainContextSubst Format 2 → SingleSubst test
   * Test runtime: 4+ seconds → 0.02 seconds (200× faster) */
  hb_face_t *face_context = hb_test_open_font_file ("fonts/ContextFormat2-Depend-Test.ttf");
  hb_subset_depend_t *depend_context = hb_subset_depend_from_face_or_fail (face_context);
  g_assert_nonnull (depend_context);

  /* ContextSubst Format 2 → MultipleSubst
   * Lookup 20: Format 2 class-based context invokes Lookup 17 (MultipleSubst) */
  g_test_message ("Testing ContextSubst Format 2 → MultipleSubst: YehBarreeFin (252) → YehBarreeFin_3 (255)");
  g_assert_true (find_dependency (depend_context, 252, 255, HB_OT_TAG_GSUB,
                                  NULL, NULL));

  /* ChainContextSubst Format 2 → SingleSubst
   * Lookup 25: Format 2 class-based chain context with lookahead invokes Lookup 119 (SingleSubst)
   * When BehxIni (class 2) is followed by AlefFin (class 1), BehxIni → BehxIni.A */
  g_test_message ("Testing ChainContextSubst Format 2 → SingleSubst: BehxIni (281) → BehxIni.A (282)");
  g_assert_true (find_dependency (depend_context, 281, 282, HB_OT_TAG_GSUB,
                                  NULL, NULL));

  /* ADDITIONAL REGRESSION TESTS
   *
   * The sequential accumulation and nested context bug fixes are also
   * comprehensively tested by the depend fuzzer with these seeds:
   *   - 0x4388c9ba4973f4f9 (sequential accumulation bug)
   *   - 0x5a50e64a753f3298 (nested context bug)
   *
   * The fuzzer verifies depend closure matches subset closure across
   * 1024 randomized test cases per font.
   */

  /* Negative test: verify contextual filtering (issue #3397)
   * Lookup 10 covers {AlefFin, LamIni, LamMed} but Lookup 9's SubRuleSet for LamIni
   * only has LamIni in position 0. LamMed→LamFin.LA is unreachable from this context. */
  g_test_message ("Testing contextual filtering: LamIni (416) should NOT depend on LamFin.LA (268)");
  g_assert_false (find_dependency (depend_context, 416, 268, HB_OT_TAG_GSUB,
                                   NULL, NULL));

  hb_subset_depend_destroy (depend_context);
  hb_face_destroy (face_context);

  /* ChainContextSubst Format 3 → MultipleSubst + feature tagging */
  face_source = hb_test_open_font_file ("fonts/SourceSansPro-Regular.otf");
  depend_source = hb_subset_depend_from_face_or_fail (face_source);
  g_assert_nonnull (depend_source);

  /* Lookup 8: Format 3 chain context invokes Lookup 7 (MultipleSubst)
   * Also verifies contextual recursion propagates feature tags */
  g_test_message ("Testing ChainContextSubst Format 3 → MultipleSubst: Ecircumflex (92) → E (6) with ccmp");
  layout_tag = HB_TAG('c','c','m','p');
  g_assert_true (find_dependency (depend_source, 92, 6, HB_OT_TAG_GSUB,
                                  &layout_tag, NULL));

  hb_subset_depend_destroy (depend_source);
  hb_face_destroy (face_source);
}

static void
test_depend_varc (void)
{
  hb_face_t *face = hb_test_open_font_file ("fonts/varc-ac00-ac01.ttf");
  hb_subset_depend_t *depend = hb_subset_depend_from_face_or_fail (face);
  g_assert_nonnull (depend);

  /* uniAC00 (1) has two direct VARC components (3 and 5). */
  g_assert_true (find_dependency (depend, 1, 3, HB_TAG ('V','A','R','C'),
				  NULL, NULL));
  g_assert_true (find_dependency (depend, 1, 5, HB_TAG ('V','A','R','C'),
				  NULL, NULL));

  hb_subset_depend_destroy (depend);
  hb_face_destroy (face);
}

int
main (int argc, char **argv)
{
  hb_test_init (&argc, &argv);

  hb_test_add (test_depend_glyf);
  hb_test_add (test_depend_cff);
  hb_test_add (test_depend_colr);
  hb_test_add (test_depend_math);
  hb_test_add (test_depend_varc);
  hb_test_add (test_depend_gsub_formats);

  return hb_test_run ();
}

#else

int
main (int argc, char **argv)
{
  g_test_init (&argc, &argv, NULL);
  g_test_skip ("HB_DEPEND_API not enabled");
  return 0;
}

#endif
