/**
 * Lazily evaluate static conditions for `static if`, `static assert` and template constraints.
 *
 * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
 * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
 * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
 * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/staticcond.d, _staticcond.d)
 * Documentation:  https://dlang.org/phobos/dmd_staticcond.html
 * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/staticcond.d
 */

module dmd.staticcond;

import dmd.arraytypes;
import dmd.dmodule;
import dmd.dscope;
import dmd.dsymbol;
import dmd.errors;
import dmd.expression;
import dmd.expressionsem;
import dmd.globals;
import dmd.identifier;
import dmd.mtype;
import dmd.root.array;
import dmd.common.outbuffer;
import dmd.tokens;



/********************************************
 * Semantically analyze and then evaluate a static condition at compile time.
 * This is special because short circuit operators &&, || and ?: at the top
 * level are not semantically analyzed if the result of the expression is not
 * necessary.
 * Params:
 *      sc  = instantiating scope
 *      original = original expression, for error messages
 *      e =  resulting expression
 *      errors = set to `true` if errors occurred
 *      negatives = array to store negative clauses
 * Returns:
 *      true if evaluates to true
 */
bool evalStaticCondition(Scope* sc, Expression original, Expression e, out bool errors, Expressions* negatives = null)
{
    if (negatives)
        negatives.setDim(0);

    bool impl(Expression e)
    {
        if (e.isNotExp())
        {
            NotExp ne = cast(NotExp)e;
            return !impl(ne.e1);
        }

        if (e.op == EXP.andAnd || e.op == EXP.orOr)
        {
            LogicalExp aae = cast(LogicalExp)e;
            bool result = impl(aae.e1);
            if (errors)
                return false;
            if (e.op == EXP.andAnd)
            {
                if (!result)
                    return false;
            }
            else
            {
                if (result)
                    return true;
            }
            result = impl(aae.e2);
            return !errors && result;
        }

        if (e.op == EXP.question)
        {
            CondExp ce = cast(CondExp)e;
            bool result = impl(ce.econd);
            if (errors)
                return false;
            Expression leg = result ? ce.e1 : ce.e2;
            result = impl(leg);
            return !errors && result;
        }

        Expression before = e;
        const uint nerrors = global.errors;

        sc = sc.startCTFE();
        sc.flags |= SCOPE.condition;

        e = e.expressionSemantic(sc);
        e = resolveProperties(sc, e);
        e = e.toBoolean(sc);

        sc = sc.endCTFE();
        e = e.optimize(WANTvalue);

        if (nerrors != global.errors ||
            e.isErrorExp() ||
            e.type.toBasetype() == Type.terror)
        {
            errors = true;
            return false;
        }

        e = e.ctfeInterpret();

        const opt = e.toBool();
        if (opt.isEmpty())
        {
            e.error("expression `%s` is not constant", e.toChars());
            errors = true;
            return false;
        }

        if (negatives && !opt.get())
            negatives.push(before);
        return opt.get();
    }
    return impl(e);
}

/********************************************
 * Format a static condition as a tree-like structure, marking failed and
 * bypassed expressions.
 * Params:
 *      original = original expression
 *      instantiated = instantiated expression
 *      negatives = array with negative clauses from `instantiated` expression
 *      full = controls whether it shows the full output or only failed parts
 *      itemCount = returns the number of written clauses
 * Returns:
 *      formatted string or `null` if the expressions were `null`, or if the
 *      instantiated expression is not based on the original one
 */
const(char)* visualizeStaticCondition(Expression original, Expression instantiated,
    const Expression[] negatives, bool full, ref uint itemCount)
{
    if (!original || !instantiated || original.loc !is instantiated.loc)
        return null;

    OutBuffer buf;

    if (full)
        itemCount = visualizeFull(original, instantiated, negatives, buf);
    else
        itemCount = visualizeShort(original, instantiated, negatives, buf);

    return buf.extractChars();
}

private uint visualizeFull(Expression original, Expression instantiated,
    const Expression[] negatives, ref OutBuffer buf)
{
    // tree-like structure; traverse and format simultaneously
    uint count;
    uint indent;

    static void printOr(uint indent, ref OutBuffer buf)
    {
        buf.reserve(indent * 4 + 8);
        foreach (i; 0 .. indent)
            buf.writestring("    ");
        buf.writestring("    or:\n");
    }

    // returns true if satisfied
    bool impl(Expression orig, Expression e, bool inverted, bool orOperand, bool unreached)
    {
        EXP op = orig.op;

        // lower all 'not' to the bottom
        // !(A && B) -> !A || !B
        // !(A || B) -> !A && !B
        if (inverted)
        {
            if (op == EXP.andAnd)
                op = EXP.orOr;
            else if (op == EXP.orOr)
                op = EXP.andAnd;
        }

        if (op == EXP.not)
        {
            NotExp no = cast(NotExp)orig;
            NotExp ne = cast(NotExp)e;
            assert(ne);
            return impl(no.e1, ne.e1, !inverted, orOperand, unreached);
        }
        else if (op == EXP.andAnd)
        {
            BinExp bo = cast(BinExp)orig;
            BinExp be = cast(BinExp)e;
            assert(be);
            const r1 = impl(bo.e1, be.e1, inverted, false, unreached);
            const r2 = impl(bo.e2, be.e2, inverted, false, unreached || !r1);
            return r1 && r2;
        }
        else if (op == EXP.orOr)
        {
            if (!orOperand) // do not indent A || B || C twice
                indent++;
            BinExp bo = cast(BinExp)orig;
            BinExp be = cast(BinExp)e;
            assert(be);
            const r1 = impl(bo.e1, be.e1, inverted, true, unreached);
            printOr(indent, buf);
            const r2 = impl(bo.e2, be.e2, inverted, true, unreached);
            if (!orOperand)
                indent--;
            return r1 || r2;
        }
        else if (op == EXP.question)
        {
            CondExp co = cast(CondExp)orig;
            CondExp ce = cast(CondExp)e;
            assert(ce);
            if (!inverted)
            {
                // rewrite (A ? B : C) as (A && B || !A && C)
                if (!orOperand)
                    indent++;
                const r1 = impl(co.econd, ce.econd, inverted, false, unreached);
                const r2 = impl(co.e1, ce.e1, inverted, false, unreached || !r1);
                printOr(indent, buf);
                const r3 = impl(co.econd, ce.econd, !inverted, false, unreached);
                const r4 = impl(co.e2, ce.e2, inverted, false, unreached || !r3);
                if (!orOperand)
                    indent--;
                return r1 && r2 || r3 && r4;
            }
            else
            {
                // rewrite !(A ? B : C) as (!A || !B) && (A || !C)
                if (!orOperand)
                    indent++;
                const r1 = impl(co.econd, ce.econd, inverted, false, unreached);
                printOr(indent, buf);
                const r2 = impl(co.e1, ce.e1, inverted, false, unreached);
                const r12 = r1 || r2;
                const r3 = impl(co.econd, ce.econd, !inverted, false, unreached || !r12);
                printOr(indent, buf);
                const r4 = impl(co.e2, ce.e2, inverted, false, unreached || !r12);
                if (!orOperand)
                    indent--;
                return (r1 || r2) && (r3 || r4);
            }
        }
        else // 'primitive' expression
        {
            buf.reserve(indent * 4 + 4);
            foreach (i; 0 .. indent)
                buf.writestring("    ");

            // find its value; it may be not computed, if there was a short circuit,
            // but we handle this case with `unreached` flag
            bool value = true;
            if (!unreached)
            {
                foreach (fe; negatives)
                {
                    if (fe is e)
                    {
                        value = false;
                        break;
                    }
                }
            }
            // write the marks first
            const satisfied = inverted ? !value : value;
            if (!satisfied && !unreached)
                buf.writestring("  > ");
            else if (unreached)
                buf.writestring("  - ");
            else
                buf.writestring("    ");
            // then the expression itself
            if (inverted)
                buf.writeByte('!');
            buf.writestring(orig.toChars);
            buf.writenl();
            count++;
            return satisfied;
        }
    }

    impl(original, instantiated, false, true, false);
    return count;
}

private uint visualizeShort(Expression original, Expression instantiated,
    const Expression[] negatives, ref OutBuffer buf)
{
    // simple list; somewhat similar to long version, so no comments
    // one difference is that it needs to hold items to display in a stack

    static struct Item
    {
        Expression orig;
        bool inverted;
    }

    Array!Item stack;

    bool impl(Expression orig, Expression e, bool inverted)
    {
        EXP op = orig.op;

        if (inverted)
        {
            if (op == EXP.andAnd)
                op = EXP.orOr;
            else if (op == EXP.orOr)
                op = EXP.andAnd;
        }

        if (op == EXP.not)
        {
            NotExp no = cast(NotExp)orig;
            NotExp ne = cast(NotExp)e;
            assert(ne);
            return impl(no.e1, ne.e1, !inverted);
        }
        else if (op == EXP.andAnd)
        {
            BinExp bo = cast(BinExp)orig;
            BinExp be = cast(BinExp)e;
            assert(be);
            bool r = impl(bo.e1, be.e1, inverted);
            r = r && impl(bo.e2, be.e2, inverted);
            return r;
        }
        else if (op == EXP.orOr)
        {
            BinExp bo = cast(BinExp)orig;
            BinExp be = cast(BinExp)e;
            assert(be);
            const lbefore = stack.length;
            bool r = impl(bo.e1, be.e1, inverted);
            r = r || impl(bo.e2, be.e2, inverted);
            if (r)
                stack.setDim(lbefore); // purge added positive items
            return r;
        }
        else if (op == EXP.question)
        {
            CondExp co = cast(CondExp)orig;
            CondExp ce = cast(CondExp)e;
            assert(ce);
            if (!inverted)
            {
                const lbefore = stack.length;
                bool a = impl(co.econd, ce.econd, inverted);
                a = a && impl(co.e1, ce.e1, inverted);
                bool b;
                if (!a)
                {
                    b = impl(co.econd, ce.econd, !inverted);
                    b = b && impl(co.e2, ce.e2, inverted);
                }
                const r = a || b;
                if (r)
                    stack.setDim(lbefore);
                return r;
            }
            else
            {
                bool a;
                {
                    const lbefore = stack.length;
                    a = impl(co.econd, ce.econd, inverted);
                    a = a || impl(co.e1, ce.e1, inverted);
                    if (a)
                        stack.setDim(lbefore);
                }
                bool b;
                if (a)
                {
                    const lbefore = stack.length;
                    b = impl(co.econd, ce.econd, !inverted);
                    b = b || impl(co.e2, ce.e2, inverted);
                    if (b)
                        stack.setDim(lbefore);
                }
                return a && b;
            }
        }
        else // 'primitive' expression
        {
            bool value = true;
            foreach (fe; negatives)
            {
                if (fe is e)
                {
                    value = false;
                    break;
                }
            }
            const satisfied = inverted ? !value : value;
            if (!satisfied)
                stack.push(Item(orig, inverted));
            return satisfied;
        }
    }

    impl(original, instantiated, false);

    foreach (i; 0 .. stack.length)
    {
        // write the expression only
        buf.writestring("       ");
        if (stack[i].inverted)
            buf.writeByte('!');
        buf.writestring(stack[i].orig.toChars);
        // here with no trailing newline
        if (i + 1 < stack.length)
            buf.writenl();
    }
    return cast(uint)stack.length;
}
