import { assert } from "../../../../../../assert.js";
import { NULL_POINTER } from "../BinaryTopology.js";

/**
 * Find the loop in `face_a` whose edge is shared with `face_b`.
 *
 * The returned loop belongs to `face_a` and its edge is also used by a loop in `face_b`.
 * Combined with {@link BinaryTopology#loop_read_vertex} and {@link BinaryTopology#loop_read_next},
 * this is enough to read the two vertices of the shared edge in `face_a`'s winding order,
 * which is useful for constructing directed portals.
 *
 * @param {BinaryTopology} mesh
 * @param {number} face_a
 * @param {number} face_b
 * @returns {number} loop ID in `face_a` that shares an edge with `face_b`, or {@link NULL_POINTER} if no shared edge exists
 */
export function bt_faces_shared_loop(mesh, face_a, face_b) {
    assert.defined(mesh, "mesh");
    assert.notNull(mesh, "mesh");
    assert.equal(mesh.isBinaryTopology, true, "mesh.isBinaryTopology !== true");
    assert.isNonNegativeInteger(face_a, "face_a");
    assert.isNonNegativeInteger(face_b, "face_b");

    const start_loop = mesh.face_read_loop(face_a);

    if (start_loop === NULL_POINTER) {
        return NULL_POINTER;
    }

    let current_loop = start_loop;

    do {
        // walk the radial cycle around the edge of this loop
        let radial_loop = mesh.loop_read_radial_next(current_loop);

        while (radial_loop !== current_loop) {
            if (mesh.loop_read_face(radial_loop) === face_b) {
                return current_loop;
            }

            radial_loop = mesh.loop_read_radial_next(radial_loop);
        }

        current_loop = mesh.loop_read_next(current_loop);
    } while (current_loop !== start_loop);

    return NULL_POINTER;
}
