/**
 * @fileoverview A class of the code path segment.
 * @author Toru Nagashima
 */

"use strict";

//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------

const debug = require("./debug-helpers");

//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------

/**
 * Checks whether or not a given segment is reachable.
 *
 * @param {CodePathSegment} segment - A segment to check.
 * @returns {boolean} `true` if the segment is reachable.
 */
function isReachable(segment) {
    return segment.reachable;
}

//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------

/**
 * A code path segment.
 */
class CodePathSegment {

    /**
     * @param {string} id - An identifier.
     * @param {CodePathSegment[]} allPrevSegments - An array of the previous segments.
     *   This array includes unreachable segments.
     * @param {boolean} reachable - A flag which shows this is reachable.
     */
    constructor(id, allPrevSegments, reachable) {

        /**
         * The identifier of this code path.
         * Rules use it to store additional information of each rule.
         * @type {string}
         */
        this.id = id;

        /**
         * An array of the next segments.
         * @type {CodePathSegment[]}
         */
        this.nextSegments = [];

        /**
         * An array of the previous segments.
         * @type {CodePathSegment[]}
         */
        this.prevSegments = allPrevSegments.filter(isReachable);

        /**
         * An array of the next segments.
         * This array includes unreachable segments.
         * @type {CodePathSegment[]}
         */
        this.allNextSegments = [];

        /**
         * An array of the previous segments.
         * This array includes unreachable segments.
         * @type {CodePathSegment[]}
         */
        this.allPrevSegments = allPrevSegments;

        /**
         * A flag which shows this is reachable.
         * @type {boolean}
         */
        this.reachable = reachable;

        // Internal data.
        Object.defineProperty(this, "internal", {
            value: {
                used: false,
                loopedPrevSegments: []
            }
        });

        /* istanbul ignore if */
        if (debug.enabled) {
            this.internal.nodes = [];
            this.internal.exitNodes = [];
        }
    }

    /**
     * Checks a given previous segment is coming from the end of a loop.
     *
     * @param {CodePathSegment} segment - A previous segment to check.
     * @returns {boolean} `true` if the segment is coming from the end of a loop.
     */
    isLoopedPrevSegment(segment) {
        return this.internal.loopedPrevSegments.indexOf(segment) !== -1;
    }

    /**
     * Creates the root segment.
     *
     * @param {string} id - An identifier.
     * @returns {CodePathSegment} The created segment.
     */
    static newRoot(id) {
        return new CodePathSegment(id, [], true);
    }

    /**
     * Creates a segment that follows given segments.
     *
     * @param {string} id - An identifier.
     * @param {CodePathSegment[]} allPrevSegments - An array of the previous segments.
     * @returns {CodePathSegment} The created segment.
     */
    static newNext(id, allPrevSegments) {
        return new CodePathSegment(
            id,
            CodePathSegment.flattenUnusedSegments(allPrevSegments),
            allPrevSegments.some(isReachable)
        );
    }

    /**
     * Creates an unreachable segment that follows given segments.
     *
     * @param {string} id - An identifier.
     * @param {CodePathSegment[]} allPrevSegments - An array of the previous segments.
     * @returns {CodePathSegment} The created segment.
     */
    static newUnreachable(id, allPrevSegments) {
        const segment = new CodePathSegment(id, CodePathSegment.flattenUnusedSegments(allPrevSegments), false);

        /*
         * In `if (a) return a; foo();` case, the unreachable segment preceded by
         * the return statement is not used but must not be remove.
         */
        CodePathSegment.markUsed(segment);

        return segment;
    }

    /**
     * Creates a segment that follows given segments.
     * This factory method does not connect with `allPrevSegments`.
     * But this inherits `reachable` flag.
     *
     * @param {string} id - An identifier.
     * @param {CodePathSegment[]} allPrevSegments - An array of the previous segments.
     * @returns {CodePathSegment} The created segment.
     */
    static newDisconnected(id, allPrevSegments) {
        return new CodePathSegment(id, [], allPrevSegments.some(isReachable));
    }

    /**
     * Makes a given segment being used.
     *
     * And this function registers the segment into the previous segments as a next.
     *
     * @param {CodePathSegment} segment - A segment to mark.
     * @returns {void}
     */
    static markUsed(segment) {
        if (segment.internal.used) {
            return;
        }
        segment.internal.used = true;

        let i;

        if (segment.reachable) {
            for (i = 0; i < segment.allPrevSegments.length; ++i) {
                const prevSegment = segment.allPrevSegments[i];

                prevSegment.allNextSegments.push(segment);
                prevSegment.nextSegments.push(segment);
            }
        } else {
            for (i = 0; i < segment.allPrevSegments.length; ++i) {
                segment.allPrevSegments[i].allNextSegments.push(segment);
            }
        }
    }

    /**
     * Marks a previous segment as looped.
     *
     * @param {CodePathSegment} segment - A segment.
     * @param {CodePathSegment} prevSegment - A previous segment to mark.
     * @returns {void}
     */
    static markPrevSegmentAsLooped(segment, prevSegment) {
        segment.internal.loopedPrevSegments.push(prevSegment);
    }

    /**
     * Replaces unused segments with the previous segments of each unused segment.
     *
     * @param {CodePathSegment[]} segments - An array of segments to replace.
     * @returns {CodePathSegment[]} The replaced array.
     */
    static flattenUnusedSegments(segments) {
        const done = Object.create(null);
        const retv = [];

        for (let i = 0; i < segments.length; ++i) {
            const segment = segments[i];

            // Ignores duplicated.
            if (done[segment.id]) {
                continue;
            }

            // Use previous segments if unused.
            if (!segment.internal.used) {
                for (let j = 0; j < segment.allPrevSegments.length; ++j) {
                    const prevSegment = segment.allPrevSegments[j];

                    if (!done[prevSegment.id]) {
                        done[prevSegment.id] = true;
                        retv.push(prevSegment);
                    }
                }
            } else {
                done[segment.id] = true;
                retv.push(segment);
            }
        }

        return retv;
    }
}

module.exports = CodePathSegment;
