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

/**
 *
 * @param {TetrahedralMesh} mesh
 * @param {number} point_count number of points (vertices) in the mesh
 * @return {number[]} Lines, each line is two indices, [a, b]
 */
export function build_tetrahedral_mesh_geometry_lines(mesh, point_count) {
    assert.isNonNegativeInteger(point_count, 'point_count');
    assert.defined(mesh, 'tetrahedra');
    assert.equal(mesh.isTetrahedralMesh, true, 'mesh.isTetrahedralMesh !== true');

    /**
     *
     * @type {number[]}
     */
    const lines = [];

    /**
     * Hash for tracking duplicate edges
     * @type {Object<boolean>}
     */
    const occupancy = {};

    assert.isNonNegativeInteger(point_count, 'point_count');

    /**
     *
     * @param {number} a
     * @param {number} b
     */
    function ensure_line(a, b) {
        assert.isNonNegativeInteger(a, 'a');
        assert.isNonNegativeInteger(b, 'b');

        assert.lessThan(a, point_count, 'index A is out of bounds');
        assert.lessThan(b, point_count, 'index B is out of bounds');

        // sort vertices
        let v0, v1;

        if (a < b) {
            v0 = a;
            v1 = b;
        } else {
            v0 = b;
            v1 = a;
        }

        const key = `${v0}_${v1}`;

        if (occupancy.hasOwnProperty(key)) {
            // already recorded
            return;
        }

        occupancy[key] = true;

        // no line record yet, create it
        lines.push(v0, v1);
    }

    mesh.forEach((tet, mesh) => {
        assert.ok(mesh.exists(tet), `Visited un-allocated tet ${tet}`);

        const a = mesh.getVertexIndex(tet, 0);
        const b = mesh.getVertexIndex(tet, 1);
        const c = mesh.getVertexIndex(tet, 2);
        const d = mesh.getVertexIndex(tet, 3);

        ensure_line(a, b);
        ensure_line(a, c);
        ensure_line(a, d);

        ensure_line(b, c);
        ensure_line(c, d);
        ensure_line(b, d);
    })

    return lines;
}