/* Compiler implementation of the D programming language
 * Copyright (C) 1999-2021 by The D Language Foundation, All Rights Reserved
 * written by Walter Bright
 * http://www.digitalmars.com
 * Distributed under the Boost Software License, Version 1.0.
 * http://www.boost.org/LICENSE_1_0.txt
 * https://github.com/D-Programming-Language/dmd/blob/master/src/access.c
 */

#include "root/dsystem.h"
#include "root/root.h"
#include "root/rmem.h"

#include "errors.h"
#include "enum.h"
#include "aggregate.h"
#include "init.h"
#include "attrib.h"
#include "scope.h"
#include "id.h"
#include "mtype.h"
#include "declaration.h"
#include "aggregate.h"
#include "expression.h"
#include "module.h"
#include "template.h"

/* Code to do access checks
 */

bool hasPackageAccess(Scope *sc, Dsymbol *s);
bool hasPackageAccess(Module *mod, Dsymbol *s);
bool hasPrivateAccess(AggregateDeclaration *ad, Dsymbol *smember);
bool isFriendOf(AggregateDeclaration *ad, AggregateDeclaration *cd);
static Dsymbol *mostVisibleOverload(Dsymbol *s);

/****************************************
 * Return Prot access for Dsymbol smember in this declaration.
 */
Prot getAccess(AggregateDeclaration *ad, Dsymbol *smember)
{
    Prot access_ret = Prot(Prot::none);

    assert(ad->isStructDeclaration() || ad->isClassDeclaration());
    if (smember->toParent() == ad)
    {
        access_ret = smember->prot();
    }
    else if (smember->isDeclaration()->isStatic())
    {
        access_ret = smember->prot();
    }
    if (ClassDeclaration *cd = ad->isClassDeclaration())
    {
        for (size_t i = 0; i < cd->baseclasses->length; i++)
        {
            BaseClass *b = (*cd->baseclasses)[i];

            Prot access = getAccess(b->sym, smember);
            switch (access.kind)
            {
                case Prot::none:
                    break;

                case Prot::private_:
                    access_ret = Prot(Prot::none);  // private members of base class not accessible
                    break;

                case Prot::package_:
                case Prot::protected_:
                case Prot::public_:
                case Prot::export_:
                    // If access is to be tightened
                    if (Prot::public_ < access.kind)
                        access = Prot(Prot::public_);

                    // Pick path with loosest access
                    if (access_ret.isMoreRestrictiveThan(access))
                        access_ret = access;
                    break;

                default:
                    assert(0);
            }
        }
    }

    return access_ret;
}

/********************************************************
 * Helper function for checkAccess()
 * Returns:
 *      false   is not accessible
 *      true    is accessible
 */
static bool isAccessible(
        Dsymbol *smember,
        Dsymbol *sfunc,
        AggregateDeclaration *dthis,
        AggregateDeclaration *cdscope)
{
    assert(dthis);

    if (hasPrivateAccess(dthis, sfunc) ||
        isFriendOf(dthis, cdscope))
    {
        if (smember->toParent() == dthis)
            return true;

        if (ClassDeclaration *cdthis = dthis->isClassDeclaration())
        {
            for (size_t i = 0; i < cdthis->baseclasses->length; i++)
            {
                BaseClass *b = (*cdthis->baseclasses)[i];
                Prot access = getAccess(b->sym, smember);
                if (access.kind >= Prot::protected_ ||
                    isAccessible(smember, sfunc, b->sym, cdscope))
                {
                    return true;
                }
            }
        }
    }
    else
    {
        if (smember->toParent() != dthis)
        {
            if (ClassDeclaration *cdthis = dthis->isClassDeclaration())
            {
                for (size_t i = 0; i < cdthis->baseclasses->length; i++)
                {
                    BaseClass *b = (*cdthis->baseclasses)[i];
                    if (isAccessible(smember, sfunc, b->sym, cdscope))
                        return true;
                }
            }
        }
    }
    return false;
}

/*******************************
 * Do access check for member of this class, this class being the
 * type of the 'this' pointer used to access smember.
 * Returns true if the member is not accessible.
 */
bool checkAccess(AggregateDeclaration *ad, Loc loc, Scope *sc, Dsymbol *smember)
{
    FuncDeclaration *f = sc->func;
    AggregateDeclaration *cdscope = sc->getStructClassScope();

    Dsymbol *smemberparent = smember->toParent();
    if (!smemberparent || !smemberparent->isAggregateDeclaration())
    {
        return false;                   // then it is accessible
    }

    // BUG: should enable this check
    //assert(smember->parent->isBaseOf(this, NULL));

    bool result;
    Prot access;
    if (smemberparent == ad)
    {
        access = smember->prot();
        result = access.kind >= Prot::public_ ||
                 hasPrivateAccess(ad, f) ||
                 isFriendOf(ad, cdscope) ||
                 (access.kind == Prot::package_ && hasPackageAccess(sc, smember)) ||
                 ad->getAccessModule() == sc->_module;
    }
    else if ((access = getAccess(ad, smember)).kind >= Prot::public_)
    {
        result = true;
    }
    else if (access.kind == Prot::package_ && hasPackageAccess(sc, ad))
    {
        result = true;
    }
    else
    {
        result = isAccessible(smember, f, ad, cdscope);
    }
    if (!result)
    {
        ad->error(loc, "member %s is not accessible", smember->toChars());
        //printf("smember = %s %s, prot = %d, semanticRun = %d\n",
        //        smember->kind(), smember->toPrettyChars(), smember->prot(), smember->semanticRun);
        return true;
    }
    return false;
}

/****************************************
 * Determine if this is the same or friend of cd.
 */
bool isFriendOf(AggregateDeclaration *ad, AggregateDeclaration *cd)
{
    if (ad == cd)
        return true;

    // Friends if both are in the same module
    //if (toParent() == cd->toParent())
    if (cd && ad->getAccessModule() == cd->getAccessModule())
    {
        return true;
    }

    return false;
}

/****************************************
 * Determine if scope sc has package level access to s.
 */
bool hasPackageAccess(Scope *sc, Dsymbol *s)
{
    return hasPackageAccess(sc->_module, s);
}

bool hasPackageAccess(Module *mod, Dsymbol *s)
{
    Package *pkg = NULL;

    if (s->prot().pkg)
        pkg = s->prot().pkg;
    else
    {
        // no explicit package for protection, inferring most qualified one
        for (; s; s = s->parent)
        {
            if (Module *m = s->isModule())
            {
                DsymbolTable *dst = Package::resolve(m->md ? m->md->packages : NULL, NULL, NULL);
                assert(dst);
                Dsymbol *s2 = dst->lookup(m->ident);
                assert(s2);
                Package *p = s2->isPackage();
                if (p && p->isPackageMod())
                {
                    pkg = p;
                    break;
                }
            }
            else if ((pkg = s->isPackage()) != NULL)
                break;
        }
    }

    if (pkg)
    {
        if (pkg == mod->parent)
        {
            return true;
        }
        if (pkg->isPackageMod() == mod)
        {
            return true;
        }
        Dsymbol* ancestor = mod->parent;
        for (; ancestor; ancestor = ancestor->parent)
        {
            if (ancestor == pkg)
            {
                return true;
            }
        }
    }

    return false;
}

/****************************************
 * Determine if scope sc has protected level access to cd.
 */
bool hasProtectedAccess(Scope *sc, Dsymbol *s)
{
    if (ClassDeclaration *cd = s->isClassMember()) // also includes interfaces
    {
        for (Scope *scx = sc; scx; scx = scx->enclosing)
        {
            if (!scx->scopesym)
                continue;
            ClassDeclaration *cd2 = scx->scopesym->isClassDeclaration();
            if (cd2 && cd->isBaseOf(cd2, NULL))
                return true;
        }
    }
    return sc->_module == s->getAccessModule();
}

/**********************************
 * Determine if smember has access to private members of this declaration.
 */
bool hasPrivateAccess(AggregateDeclaration *ad, Dsymbol *smember)
{
    if (smember)
    {
        AggregateDeclaration *cd = NULL;
        Dsymbol *smemberparent = smember->toParent();
        if (smemberparent)
            cd = smemberparent->isAggregateDeclaration();

        if (ad == cd)         // smember is a member of this class
        {
            return true;           // so we get private access
        }

        // If both are members of the same module, grant access
        while (1)
        {
            Dsymbol *sp = smember->toParent();
            if (sp->isFuncDeclaration() && smember->isFuncDeclaration())
                smember = sp;
            else
                break;
        }
        if (!cd && ad->toParent() == smember->toParent())
        {
            return true;
        }
        if (!cd && ad->getAccessModule() == smember->getAccessModule())
        {
            return true;
        }
    }
    return false;
}

/****************************************
 * Check access to d for expression e.d
 * Returns true if the declaration is not accessible.
 */
bool checkAccess(Loc loc, Scope *sc, Expression *e, Declaration *d)
{
    if (sc->flags & SCOPEnoaccesscheck)
        return false;

    if (d->isUnitTestDeclaration())
    {
        // Unittests are always accessible.
        return false;
    }
    if (!e)
        return false;

    if (e->type->ty == Tclass)
    {
        // Do access check
        ClassDeclaration *cd = (ClassDeclaration *)(((TypeClass *)e->type)->sym);
        if (e->op == TOKsuper)
        {
            ClassDeclaration *cd2 = sc->func->toParent()->isClassDeclaration();
            if (cd2)
                cd = cd2;
        }
        return checkAccess(cd, loc, sc, d);
    }
    else if (e->type->ty == Tstruct)
    {
        // Do access check
        StructDeclaration *cd = (StructDeclaration *)(((TypeStruct *)e->type)->sym);
        return checkAccess(cd, loc, sc, d);
    }
    return false;
}

/****************************************
 * Check access to package/module `p` from scope `sc`.
 *
 * Params:
 *   loc = source location for issued error message
 *   sc = scope from which to access to a fully qualified package name
 *   p = the package/module to check access for
 * Returns: true if the package is not accessible.
 *
 * Because a global symbol table tree is used for imported packages/modules,
 * access to them needs to be checked based on the imports in the scope chain
 * (see Bugzilla 313).
 *
 */
bool checkAccess(Scope *sc, Package *p)
{
    if (sc->_module == p)
        return false;
    for (; sc; sc = sc->enclosing)
    {
        if (sc->scopesym && sc->scopesym->isPackageAccessible(p, Prot(Prot::private_)))
            return false;
    }

    return true;
}

/**
 * Check whether symbols `s` is visible in `mod`.
 *
 * Params:
 *  mod = lookup origin
 *  s = symbol to check for visibility
 * Returns: true if s is visible in mod
 */
bool symbolIsVisible(Module *mod, Dsymbol *s)
{
    // should sort overloads by ascending protection instead of iterating here
    s = mostVisibleOverload(s);

    switch (s->prot().kind)
    {
        case Prot::undefined:
            return true;
        case Prot::none:
            return false; // no access
        case Prot::private_:
            return s->getAccessModule() == mod;
        case Prot::package_:
            return s->getAccessModule() == mod || hasPackageAccess(mod, s);
        case Prot::protected_:
            return s->getAccessModule() == mod;
        case Prot::public_:
        case Prot::export_:
            return true;
        default:
            assert(0);
    }
    return false;
}

/**
 * Same as above, but determines the lookup module from symbols `origin`.
 */
bool symbolIsVisible(Dsymbol *origin, Dsymbol *s)
{
    return symbolIsVisible(origin->getAccessModule(), s);
}

/**
 * Same as above but also checks for protected symbols visible from scope `sc`.
 * Used for qualified name lookup.
 *
 * Params:
 *  sc = lookup scope
 *  s = symbol to check for visibility
 * Returns: true if s is visible by origin
 */
bool symbolIsVisible(Scope *sc, Dsymbol *s)
{
    s = mostVisibleOverload(s);

    switch (s->prot().kind)
    {
        case Prot::undefined:
            return true;
        case Prot::none:
            return false; // no access
        case Prot::private_:
            return sc->_module == s->getAccessModule();
        case Prot::package_:
            return sc->_module == s->getAccessModule() || hasPackageAccess(sc->_module, s);
        case Prot::protected_:
            return hasProtectedAccess(sc, s);
        case Prot::public_:
        case Prot::export_:
            return true;
        default:
            assert(0);
    }
    return false;
}

/**
 * Use the most visible overload to check visibility. Later perform an access
 * check on the resolved overload.  This function is similar to overloadApply,
 * but doesn't recurse nor resolve aliases because protection/visibility is an
 * attribute of the alias not the aliasee.
 */
static Dsymbol *mostVisibleOverload(Dsymbol *s)
{
    if (!s->isOverloadable())
        return s;

    Dsymbol *next = NULL;
    Dsymbol *fstart = s;
    Dsymbol *mostVisible = s;
    for (; s; s = next)
    {
        // void func() {}
        // private void func(int) {}
        if (FuncDeclaration *fd = s->isFuncDeclaration())
            next = fd->overnext;
        // template temp(T) {}
        // private template temp(T:int) {}
        else if (TemplateDeclaration *td = s->isTemplateDeclaration())
            next = td->overnext;
        // alias common = mod1.func1;
        // alias common = mod2.func2;
        else if (FuncAliasDeclaration *fa = s->isFuncAliasDeclaration())
            next = fa->overnext;
        // alias common = mod1.templ1;
        // alias common = mod2.templ2;
        else if (OverDeclaration *od = s->isOverDeclaration())
            next = od->overnext;
        // alias name = sym;
        // private void name(int) {}
        else if (AliasDeclaration *ad = s->isAliasDeclaration())
        {
            if (!ad->isOverloadable())
            {
                //printf("Non overloadable Aliasee in overload list\n");
                assert(0);
            }
            // Yet unresolved aliases store overloads in overnext.
            if (ad->semanticRun < PASSsemanticdone)
                next = ad->overnext;
            else
            {
                /* This is a bit messy due to the complicated implementation of
                 * alias.  Aliases aren't overloadable themselves, but if their
                 * Aliasee is overloadable they can be converted to an overloadable
                 * alias.
                 *
                 * This is done by replacing the Aliasee w/ FuncAliasDeclaration
                 * (for functions) or OverDeclaration (for templates) which are
                 * simply overloadable aliases w/ weird names.
                 *
                 * Usually aliases should not be resolved for visibility checking
                 * b/c public aliases to private symbols are public. But for the
                 * overloadable alias situation, the Alias (_ad_) has been moved
                 * into it's own Aliasee, leaving a shell that we peel away here.
                 */
                Dsymbol *aliasee = ad->toAlias();
                if (aliasee->isFuncAliasDeclaration() || aliasee->isOverDeclaration())
                    next = aliasee;
                else
                {
                    /* A simple alias can be at the end of a function or template overload chain.
                     * It can't have further overloads b/c it would have been
                     * converted to an overloadable alias.
                     */
                    if (ad->overnext)
                    {
                        //printf("Unresolved overload of alias\n");
                        assert(0);
                    }
                    break;
                }
            }

            // handled by overloadApply for unknown reason
            assert(next != ad); // should not alias itself
            assert(next != fstart); // should not alias the overload list itself
        }
        else
            break;

        if (next && mostVisible->prot().isMoreRestrictiveThan(next->prot()))
            mostVisible = next;
    }
    return mostVisible;
}
