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

"use strict";

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

const CodePathState = require("./code-path-state");
const IdGenerator = require("./id-generator");

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

/**
 * A code path.
 */
class CodePath {

    /**
     * Creates a new instance.
     * @param {Object} options Options for the function (see below).
     * @param {string} options.id An identifier.
     * @param {string} options.origin The type of code path origin.
     * @param {CodePath|null} options.upper The code path of the upper function scope.
     * @param {Function} options.onLooped A callback function to notify looping.
     */
    constructor({ id, origin, upper, onLooped }) {

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

        /**
         * The reason that this code path was started. May be "program",
         * "function", "class-field-initializer", or "class-static-block".
         * @type {string}
         */
        this.origin = origin;

        /**
         * The code path of the upper function scope.
         * @type {CodePath|null}
         */
        this.upper = upper;

        /**
         * The code paths of nested function scopes.
         * @type {CodePath[]}
         */
        this.childCodePaths = [];

        // Initializes internal state.
        Object.defineProperty(
            this,
            "internal",
            { value: new CodePathState(new IdGenerator(`${id}_`), onLooped) }
        );

        // Adds this into `childCodePaths` of `upper`.
        if (upper) {
            upper.childCodePaths.push(this);
        }
    }

    /**
     * Gets the state of a given code path.
     * @param {CodePath} codePath A code path to get.
     * @returns {CodePathState} The state of the code path.
     */
    static getState(codePath) {
        return codePath.internal;
    }

    /**
     * The initial code path segment.
     * @type {CodePathSegment}
     */
    get initialSegment() {
        return this.internal.initialSegment;
    }

    /**
     * Final code path segments.
     * This array is a mix of `returnedSegments` and `thrownSegments`.
     * @type {CodePathSegment[]}
     */
    get finalSegments() {
        return this.internal.finalSegments;
    }

    /**
     * Final code path segments which is with `return` statements.
     * This array contains the last path segment if it's reachable.
     * Since the reachable last path returns `undefined`.
     * @type {CodePathSegment[]}
     */
    get returnedSegments() {
        return this.internal.returnedForkContext;
    }

    /**
     * Final code path segments which is with `throw` statements.
     * @type {CodePathSegment[]}
     */
    get thrownSegments() {
        return this.internal.thrownForkContext;
    }

    /**
     * Current code path segments.
     * @type {CodePathSegment[]}
     */
    get currentSegments() {
        return this.internal.currentSegments;
    }

    /**
     * Traverses all segments in this code path.
     *
     *     codePath.traverseSegments(function(segment, controller) {
     *         // do something.
     *     });
     *
     * This method enumerates segments in order from the head.
     *
     * The `controller` object has two methods.
     *
     * - `controller.skip()` - Skip the following segments in this branch.
     * - `controller.break()` - Skip all following segments.
     * @param {Object} [options] Omittable.
     * @param {CodePathSegment} [options.first] The first segment to traverse.
     * @param {CodePathSegment} [options.last] The last segment to traverse.
     * @param {Function} callback A callback function.
     * @returns {void}
     */
    traverseSegments(options, callback) {
        let resolvedOptions;
        let resolvedCallback;

        if (typeof options === "function") {
            resolvedCallback = options;
            resolvedOptions = {};
        } else {
            resolvedOptions = options || {};
            resolvedCallback = callback;
        }

        const startSegment = resolvedOptions.first || this.internal.initialSegment;
        const lastSegment = resolvedOptions.last;

        let item = null;
        let index = 0;
        let end = 0;
        let segment = null;
        const visited = Object.create(null);
        const stack = [[startSegment, 0]];
        let skippedSegment = null;
        let broken = false;
        const controller = {
            skip() {
                if (stack.length <= 1) {
                    broken = true;
                } else {
                    skippedSegment = stack[stack.length - 2][0];
                }
            },
            break() {
                broken = true;
            }
        };

        /**
         * Checks a given previous segment has been visited.
         * @param {CodePathSegment} prevSegment A previous segment to check.
         * @returns {boolean} `true` if the segment has been visited.
         */
        function isVisited(prevSegment) {
            return (
                visited[prevSegment.id] ||
                segment.isLoopedPrevSegment(prevSegment)
            );
        }

        while (stack.length > 0) {
            item = stack[stack.length - 1];
            segment = item[0];
            index = item[1];

            if (index === 0) {

                // Skip if this segment has been visited already.
                if (visited[segment.id]) {
                    stack.pop();
                    continue;
                }

                // Skip if all previous segments have not been visited.
                if (segment !== startSegment &&
                    segment.prevSegments.length > 0 &&
                    !segment.prevSegments.every(isVisited)
                ) {
                    stack.pop();
                    continue;
                }

                // Reset the flag of skipping if all branches have been skipped.
                if (skippedSegment && segment.prevSegments.includes(skippedSegment)) {
                    skippedSegment = null;
                }
                visited[segment.id] = true;

                // Call the callback when the first time.
                if (!skippedSegment) {
                    resolvedCallback.call(this, segment, controller);
                    if (segment === lastSegment) {
                        controller.skip();
                    }
                    if (broken) {
                        break;
                    }
                }
            }

            // Update the stack.
            end = segment.nextSegments.length - 1;
            if (index < end) {
                item[1] += 1;
                stack.push([segment.nextSegments[index], 0]);
            } else if (index === end) {
                item[0] = segment.nextSegments[index];
                item[1] = 0;
            } else {
                stack.pop();
            }
        }
    }
}

module.exports = CodePath;
