/* --COPYRIGHT--,EPL
 *  Copyright (c) 2008 Texas Instruments and others.
 *  All rights reserved. This program and the accompanying materials
 *  are made available under the terms of the Eclipse Public License v1.0
 *  which accompanies this distribution, and is available at
 *  http://www.eclipse.org/legal/epl-v10.html
 * 
 *  Contributors:
 *      Texas Instruments - initial implementation
 * 
 * --/COPYRIGHT--*/
package xdc.services.spec;

import java.util.*;

public class Decl
    extends Node
{
    // Static Serialization UID
    static final long serialVersionUID = 3468768778188819860L;

    Decl              over             = null;

    // Annexable
    public interface Annexable
    {
    }

    // AuxDef
    public interface AuxDef
    {
    }

    // IsType
    public interface IsType
    {
    }

    // LocalUnit
    public interface LocalUnit
    {
        Unit getUnit();
    }

    // OverridableDef
    public interface OverridableDef
    {
    }

    // Signature
    public interface Signature
    {
        enum ObjKind { NONE, SINGLE, ARRAY };
        
        Type getType();
        String getTypeCode();
        String getTypeSig();
    }

    // Sizeable
    public interface Sizeable
    {
        void sizeof( List<String> sL );
    }

    private static void checkSig( Signature sig )
    {
        Signature.ObjKind kind = Decl.objKind(sig);
        
        if (kind == Signature.ObjKind.NONE) {
            return;
        }
        
        if (sig instanceof Decl.Field) {
            Decl.Struct str = (Decl.Struct)((Decl.Field)sig).getParent();
            if (str.getName().equals("Module_State") || str.getName().equals("Instance_State")) {
                return;
            }
        }

        Decl decl = (Decl)sig;
        Session ses = decl.getSession();
        ses.msg.error(decl.getAtom(), "bad use of Object type");
    }
    
    // overrides
    public Decl overrides()
    {
        return this.over;
    }

    // finalCheck
    void finalCheck()
    {
        super.finalCheck();

        List<? extends Decl> dL = this.getChildren();
        if (dL == null) {
            return;
        }

        for (Decl d : dL) {
            d.finalCheck();
        }
    }

    // getChildren
    public List<? extends Decl> getChildren()
    {
        return null;
    }

    // getQualName
    public String getQualName()
    {
        return this.parent.getQualName() + '.' + this.name.text;
    }

    // getXmlTag
    public String getXmlTag()
    {
        return this.getClass().getSimpleName().toLowerCase();
    }
    
    /**
     * Generate the XDoc for a Decl. Unlike other Nodes, documentation
     * for a Decl accumulates any docs coming from parent interfaces. This
     * method collects the docs from the override chain, then appends the
     * docs specific for this Decl.
     */
    void parseXDoc() {
        XDoc od = overrides() == null ? null : overrides().makeXDoc();
        this.xdoc = new XDoc(getDocs(), od, summary, isNodoc);
    }

    // objKind
    public static final Decl.Signature.ObjKind objKind( Decl.Signature sig )
    {
        return objKind(sig.getType(), sig.getTypeCode());
    }
    
    public static final Decl.Signature.ObjKind objKind( Type type, String tcode )
    {
        if (tcode.equals("O")) {
            return Decl.Signature.ObjKind.SINGLE;
        }
        else if (tcode.equals("AO")) {
            Type.Array tarr = (Type.Array)type;
            return tarr.getDim() != null ? Decl.Signature.ObjKind.ARRAY : Decl.Signature.ObjKind.NONE;
        }
        else {
            return Decl.Signature.ObjKind.NONE;
        }
    }

    // parseDocs
    void parseDocs()
    {
        super.parseDocs();

        List<? extends Decl> dL = this.getChildren();
        if (dL == null) {
            return;
        }

        for (Decl d : dL) {
            d.parseDocs();
        }
    }

    // pass1Check
    void pass1Check()
    {
        List<? extends Decl> dL = this.getChildren();
        if (dL == null) {
            return;
        }

        for (Decl d : dL) {
            d.bindParent(d instanceof Decl.EnumVal ? this.parent : this);
            Session ses = d.getSession();
            if (!ses.enterNode(d.getQualName(), d)) {
                ses.msg.error(d.name, "multiple declaration in enclosing scope");
                continue;
            }
        }
    }

    // resolve
    void resolve( Unit uspec )
    {
        // TODO: common stuff ???
    }

    // Decl.Arg
    static public class Arg
        extends Decl
        implements Decl.Signature
    {
        static final long serialVersionUID = -7298373774659045568L;

        Type              type;
        Expr              init;

        Arg( Atom name, EnumSet<Qual> quals, Type type )
        {
            this(name, quals, type, null);
        }

        Arg( Atom name, EnumSet<Qual> quals, Type type, Expr init )
        {
            this.name = name;
            this.quals = quals;
            this.type = type;
            this.init = init;
        }

        // getInit
        public final Expr getInit()
        {
            return this.init;
        }

        // getType
        public final Type getType()
        {
            return this.type;
        }

        // getTypeCode
        public final String getTypeCode()
        {
            return ((this.type == null) ? "" : this.type.tcode());
        }

        // getTypeSig
        public final String getTypeSig()
        {
            return ((this.type == null) ? "" : this.type.tsig());
        }

        // resolve
        void resolve( Unit uspec )
        {
            if (this.type != null) {
                this.type.resolve(uspec);
                if (this.init != null) {
                    this.init.resolve(uspec);
                }
            }
            
            Decl.checkSig(this);
        }
    }

    // Decl.Config
    static public class Config
        extends Decl
        implements Decl.Annexable, Decl.Signature
    {
        static final long      serialVersionUID = -3472392753188999914L;

        Type                   type;
        Expr                   init;

        static HashSet<String> reservedAttrs    = new HashSet(Arrays.asList(new String[] {
                Attr.A_Annex,
                Attr.A_CommandOption,
                Attr.A_Facet,
                Attr.A_System,
        }));

        Config( Atom name, EnumSet<Qual> quals, Type type, Expr init )
        {
            this.name = name;
            this.quals = quals;
            this.type = type;
            this.init = init;
        }
        
        // checkFacet
        private void checkFacet()
        {
            if (!this.isMeta()) {
                ses.msg.error(this.name, "@Facet configs must be metaonly");
            }
            
            Ref r = this.type.tspec().getRef();
            Node n = r.getNode();
            HashSet<String> facSet = ((Unit)this.getParent()).facSet;
            
            if (!(n instanceof Unit) || !n.hasAttr(Attr.A_Facet) || !r.getId().equals("Instance")) {
                ses.msg.error(this.name, "@Facet config types must be a @Facet Instance");
            }
            else if (facSet.contains(n.getQualName())) {
                ses.msg.error(this.name, "multiple @Facet configs of the same type");
            }
            else {
                facSet.add(n.getQualName());
            }
        }

        // finalCheck
        void finalCheck()
        {
            super.finalCheck();
            
            String tc = this.getTypeCode();

            if (this.hasAttr(Attr.A_Facet)) {
                this.checkFacet();
            }
        }
        
        // getInit
        public final Expr getInit()
        {
            return this.init;
        }

        // getType
        public final Type getType()
        {
            return this.type;
        }

        // getTypeCode
        public final String getTypeCode()
        {
            return ((this.type == null) ? "" : this.type.tcode());
        }

        // getTypeSig
        public final String getTypeSig()
        {
            return ((this.type == null) ? "" : this.type.tsig());
        }
        
        // overrides
        public final Decl.Config overrides()
        {
            return (Decl.Config) this.over;
        }

        // resolve
        void resolve( Unit uspec )
        {
            this.enterAttrs(Decl.Config.reservedAttrs);

            if (this.type != null) {
                this.type.resolve(uspec, true);
                if (this.init != null) {
                    this.init.resolve(uspec);
                }
            }
            
            Decl.checkSig(this);
        }
    }

    // Decl.Const
    static public class Const
        extends Decl
        implements Decl.AuxDef, Decl.OverridableDef, Decl.Signature
    {
        static final long serialVersionUID = -5129490619630763331L;

        Type              type;
        Expr              init;

        Const( Atom name, EnumSet<Qual> quals, Type type, Expr init )
        {
            this.name = name;
            this.quals = quals;
            this.type = type;
            this.init = init;
            
            if (this.init != null) {
                this.quals.add(Qual.FINAL);
            }
        }

        // getInit
        public final Expr getInit()
        {
            return this.init;
        }

        // getType
        public final Type getType()
        {
            return this.type;
        }

        // getTypeCode
        public final String getTypeCode()
        {
            return ((this.type == null) ? "" : this.type.tcode());
        }

        // getTypeSig
        public final String getTypeSig()
        {
            return ((this.type == null) ? "" : this.type.tsig());
        }

        // resolve
        void resolve( Unit uspec )
        {
            if (this.type != null) {
                this.type.resolve(uspec);
                if (this.init != null) {
                    this.init.resolve(uspec);
                }
                else {
                    ((Unit) this.parent).custHdr = true;
                }
            }
            
            Decl.checkSig(this);
        }
    }

    // Decl.Enum
    static public class Enum
        extends Decl
        implements Decl.AuxDef, Decl.IsType, Decl.Sizeable
    {
        static final long serialVersionUID = -7076604082337550848L;

        List<EnumVal>     vals;
        Type.Spec         rep;

        Enum( Atom name, EnumSet<Qual> quals, List<EnumVal> vals, Type.Spec rep )
        {
            this.name = name;
            this.quals = quals;
            this.vals = vals;
            this.rep = rep;
        }

        // getChildren
        public List<EnumVal> getChildren()
        {
            return this.vals;
        }

        // getRep
        public final Type.Spec getRep()
        {
            return this.rep;
        }
        
        // getVals
        public final List<EnumVal> getVals()
        {
            return this.vals;
        }

        // resolve
        void resolve( Unit uspec )
        {
            for (EnumVal e : this.vals) {
                if (e.init != null) {
                    e.init.resolve(uspec);
                }
            }
            if (this.rep != null) {
                this.rep.resolve(uspec);
            }
        }

        // sizeof
        public void sizeof( List<String> sL )
        {
            if (this.rep != null) {
                this.rep.sizeof(sL);
            }
            else {
                sL.add("N" + this.getQualName());
            }
        }
    }

    // Decl.EnumVal
    static public class EnumVal
        extends Decl
        implements Decl.AuxDef
    {
        static final long serialVersionUID = -3594208666128592956L;

        Expr              init;

        EnumVal( Atom name, EnumSet<Qual> quals, Expr init )
        {
            this.name = name;
            this.quals = quals;
            this.init = init;
        }

        // getInit
        public final Expr getInit()
        {
            return this.init;
        }
    }

    // Decl.Error
    static class Error
        extends Decl
    {
        static final long serialVersionUID = 3065995409031385368L;

        Error()
        {
        }
    }

    // Decl.Extern
    static public class Extern
        extends Decl
        implements Decl.AuxDef, Decl.Signature
    {
        static final long serialVersionUID = -5537398406232068500L;

        Type              type;
        Atom              init;

        Extern( Atom name, EnumSet<Qual> quals, Type type, Atom init )
        {
            this.name = name;
            this.quals = quals;
            this.type = type;
            this.init = init;
        }

        // finalCheck
        void finalCheck()
        {
            super.finalCheck();

            if (!this.parent.isMod()) {
                ses.msg.error(this.name, "extern declaration permitted only in modules");
            }
        }

        // getType
        public final Type getType()
        {
            return this.type;
        }

        // getTypeCode
        public final String getTypeCode()
        {
            return ((this.type == null) ? "" : this.type.tcode());
        }

        // getTypeSig
        public final String getTypeSig()
        {
            return ((this.type == null) ? "" : this.type.tsig());
        }

        // getValue
        public final String getValue()
        {
            return ((this.init == null) ? this.getQualName().replace('.', '_') : this.init.text);
        }

        // resolve
        void resolve( Unit uspec )
        {
            if (this.type != null) {
                this.type.resolve(uspec);
            }
            
            Decl.checkSig(this);
        }
    }

    // Decl.Field
    static public class Field
        extends Decl
        implements Decl.Signature
    {
        static final long serialVersionUID = 1865932903245823181L;

        Type              type;

        Field( Atom name, EnumSet<Qual> quals, Type type )
        {
            this.name = name;
            this.quals = quals;
            this.type = type;
        }

        // getType
        public final Type getType()
        {
            return this.type;
        }

        // getTypeCode
        public final String getTypeCode()
        {
            return ((this.type == null) ? "" : this.type.tcode());
        }

        // getTypeSig
        public final String getTypeSig()
        {
            return ((this.type == null) ? "" : this.type.tsig());
        }

        // resolve
        void resolve( Unit uspec )
        {
            if (this.type != null) {
                this.type.resolve(uspec);
            }
            
            Decl.checkSig(this);
        }
    }

    // Decl.Fxn
    static public class Fxn
        extends Decl
        implements Decl.Annexable, Decl.Signature
    {
        static final long      serialVersionUID = 4734759580216702060L;

        Type                   type;
        List<Arg>              args;
        boolean                isVarg;
        int                    minargc = 0;

        String				   structName = null;
        
        static HashSet<String> reservedAttrs    = new HashSet(Arrays.asList(new String[] {
                Attr.A_Annex,
                Attr.A_DirectCall,
                Attr.A_Macro,
                Attr.A_System,
        }));

        Fxn( Atom name, EnumSet<Qual> quals, Type type, List<Arg> args, boolean isVarg )
        {
            this.name = name;
            this.quals = quals;
            this.type = type;
            this.args = args;
            this.isVarg = isVarg;
        }

        // finalCheck
        void finalCheck()
        {
        	super.finalCheck();

            if (this.type == null) {
                return;
            }

            if (this.type instanceof Type.Creator && this.isStatic()) {
                ses.msg.error(this.name, "declaration must be per-instance");
            }

            Type t = this.type.root();

            if (t != null && (t instanceof Type.Fxn || t instanceof Type.Array)) {
                ses.msg.error(this.name, "function can't return functions or arrays");
            }

            if (!this.isStruct()) {
            	return;
            }
            
        	if (!this.isStatic()) {
        		ses.msg.error(this.name, "struct-qualified functions must be module-wide");
        	}

        	String fn = this.name.getText();
        	this.name.replaceText(fn.replace('.', '_'));
        	
        	int k = fn.lastIndexOf('.');
            if (k != -1) {
            	String sn = fn.substring(0, k);
            	String qn = this.parent.getQualName() + '.' + sn;
            	if (!(ses.lookup(qn) instanceof Decl.Struct)) {
            		ses.msg.error(this.name, "qualified name must reference a struct in scope");
            	}
            }
        }

        // getArgs
        public final List<Arg> getArgs()
        {
            return this.args;
        }

        // getChildren
        public List<Arg> getChildren()
        {
            return this.args;
        }
        
        // getMinArgc
        public final int getMinArgc()
        {
            return this.minargc;
        }
        
        // getStructName
        public final String getStructName()
        {
        	return this.structName;
        }
        
        // getType
        public final Type getType()
        {
            return this.type;
        }

        // getTypeCode
        public final String getTypeCode()
        {
            if (this.type == null) {
                return ("");
            }
            return this.type instanceof Type.Creator ? "C" : this.type.tcode();
        }

        // getTypeSig
        public final String getTypeSig()
        {
            if (this.type == null) {
                return "void";
            }

            String res = this.type instanceof Type.Creator ? "$Instance" : this.type.tsig();
            res += "(*)(";
            String sp = "";

            if (this.args.size() == 0 && !this.isVarg) {
                return res + "xdc_Void)";
            }

            for (Arg arg : this.args) {
                res += sp + arg.type.tsig();
                sp = ",";
            }

            res += this.isVarg ? ",...)" : ")";
            return res;
        }

        // isLoggable
        public final boolean isLoggable()
        {
            return
                !this.isMeta() &&
                !this.isSys() &&
                !this.isInternal() &&
                !this.hasAttr(Attr.A_Macro) &&
                !this.hasAttr(Attr.A_DirectCall);
        }
        
        // isStruct
        public final boolean isStruct()
        {
            return this.structName != null;
        }
        
        // isVarg
        public final boolean isVarg()
        {
            return this.isVarg;
        }
        
        // overrides
        public final Decl.Fxn overrides()
        {
            return (Decl.Fxn) this.over;
        }

        // resolve
        void resolve( Unit uspec )
        {
        	this.enterAttrs(Decl.Fxn.reservedAttrs);

            if (this.hasAttr(Attr.A_Macro)) {
                ((Unit) this.parent).custHdr = true;
            }

            if (this.type == null) {
                return;
            }


            String fn = this.name.getText();
            int k = fn.lastIndexOf('.');
            if (k != -1) {
            	this.structName = fn.substring(0, k);
            	Decl.Arg arg = new Decl.Arg(
            			new Atom("__this"),
    					EnumSet.noneOf(Qual.class),
    					new Type.Ptr(
    							new Type.Declarator(
    	    							new Type.Spec(new Ref(null, this.name.copy(this.structName)), null, false, null),
    	    							new Atom("__this")),
    	    					EnumSet.noneOf(Type.Modifier.class)),
    	    	    			null);
            	this.args.add(0, arg);
            }
            
            this.type.resolve(uspec);
            boolean defflg = false;
            for (Arg arg : this.args) {
                if (arg.init == null) {
                    if (!defflg) {
                        this.minargc++;
                    }
                    else {
                        ses.msg.error(arg.name, "default value required");
                    }
                }
                else {
                    defflg = true;
                }
                arg.resolve(uspec);
            }
            
            if (this.isStruct()) {
            	if (!(this.args.get(0).getType().tspec().getRef().getNode() instanceof Decl.Struct)) {
            		ses.msg.error(this.name, "qualified name does not reference a struct type");
            	}
            	this.minargc--;
            }
            
            Decl.checkSig(this);
        }
    }

    // Decl.Imp
    static public class Imp
        extends Decl
        implements Decl.AuxDef, Decl.LocalUnit
    {
        static final long serialVersionUID = -2L;

        Import imp;
        Sup sup;

        Imp( Atom name, Import imp )
        {
        	this(name, imp, null);
        }
        
        Imp( Atom name, Sup sup )
        {
        	this(name, null, sup);
        }
        
        private Imp( Atom name, Import imp, Sup sup )
        {
        	this.name = name;
            this.imp = imp;
            this.sup = sup;
            this.quals = EnumSet.noneOf(Qual.class);
        }

        public final void bindImport( Import imp )
        {
        	this.imp = imp;
        }

        public final Import getImport()
        {
        	return this.imp;
        }
        
        public final Unit getUnit()
        {
            return this.imp.unit;
        }
        
        // finalCheck
        void finalCheck()
        {
            super.finalCheck();

            if (this.imp == null) {
                ses.msg.error(this.name, "no corresponding import");
            }

        	boolean found = true;
            if (this.sup != null) {
            	found = false;
            	for (Unit iu : this.getUnit().getInherits()) {
            		if (iu == sup.getUnit()) {
            			found = true;
            			break;
            		}
            	}
            }
            
            if (!found) {
                ses.msg.error(this.name, "does not inherit from " + sup.getUnit().getQualName());
                throw new SessionRuntimeException("parser failed");
            }
        }
        
        // resolve
        void resolve( Unit u )
        {
        	if (this.sup != null) {
        		this.sup.resolve(u);
        	}
        }
    }

    // Decl.Proxy
    static public class Proxy
        extends Decl
        implements Decl.LocalUnit
    {
        static final long serialVersionUID = -5207411272617839552L;

        Sup               sup;

        Unit              unit;

        Proxy( Atom name, EnumSet<Qual> quals, Sup sup )
        {
            this.name = name;
            this.quals = quals;
            this.sup = sup;
        }

        // getInherits
        public final Unit getInherits()
        {
            return this.sup.unit;
        }

        // getUnit
        public final Unit getUnit()
        {
            Unit u = this.getParent().getSession().findUnit(
                    this.getParent().getQualName() + '_' + this.getName());

            return u == null ? this.sup.unit : u;
        }
    }

    // Decl.Struct
    static public class Struct
        extends Decl
        implements Decl.AuxDef, Decl.IsType, Decl.Sizeable
    {
        static final long      serialVersionUID = 8653474625146200716L;

        List<Field>            flds;
        List<String>           fldSizes;
        boolean                uflag;

        static HashSet<String> reservedAttrs    = new HashSet(Arrays.asList(new String[] {
                Attr.A_Opaque,
                Attr.A_XmlDtd,
        }));

        Struct( Atom name, EnumSet<Qual> quals, List<Field> flds, boolean uflag )
        {
            this.name = name;
            this.quals = quals;
            this.flds = flds;
            this.uflag = uflag;

            this.fldSizes = new ArrayList();
        }

        // finalCheck
        void finalCheck()
        {
            super.finalCheck();

            if (this.name.text.equals("Object")) {
                ses.msg.error(this.name, "reserved name");
            }
        }

        // getChildren
        public List<Field> getChildren()
        {
            return this.flds;
        }

        // getFields
        public final List<Field> getFields()
        {
            return this.flds;
        }

        // getSizes
        public final List<String> getSizes()
        {
            return this.fldSizes;
        }
        
        // getXmlTag
        public String getXmlTag()
        {
            return this.uflag ? "union" : "struct";
        }
        
        // isAnon
        public final boolean isAnon()
        {
            return this.name.text.startsWith("__struct__");
        }
        
        // isUnion
        public final boolean isUnion()
        {
            return this.uflag;
        }

        // resolve
        void resolve( Unit uspec )
        {
            this.enterAttrs(Decl.Struct.reservedAttrs);

            if (this.flds == null) {
                return;
            }
            
            boolean isState =
                this.getName().equals("Module_State") || this.getName().equals("Instance_State");
            
            for (Field fld : this.flds) {
                fld.resolve(uspec);
            }
            
            if (isState) {
                List<Field> fL = new ArrayList<Field>();
                for (ListIterator<Field> it = this.flds.listIterator(); it.hasNext(); ) {
                    Field fld = it.next();
                    if (Decl.objKind(fld) != Decl.Signature.ObjKind.NONE) {
                        fL.add(fld);
                        it.remove();
                    }
                }
                this.flds.addAll(fL);
            }

            for (Field fld : this.flds) {
                fld.type.sizeof(this.fldSizes);
            }
        }

        // sizeof
        public void sizeof( List<String> sL )
        {
            Unit unit = (Unit) this.parent;
            sL.add("S" + unit.getQualName() + ';' + this.name.text);
        }
    }

    // Decl.Typedef
    static public class Typedef
        extends Decl
        implements Decl.AuxDef, Decl.IsType, Decl.Signature, Decl.Sizeable
    {
        static final long      serialVersionUID = -3286912318315178858L;

        Type                   type;

        static HashSet<String> reservedAttrs    = new HashSet(Arrays
                                                        .asList(new String[] { Attr.A_Encoded,
                                                        }));

        Typedef( Atom name, EnumSet<Qual> quals, Type type )
        {
            this.name = name;
            this.quals = quals;
            this.type = type;
        }

        // getType
        public final Type getType()
        {
            return this.type;
        }

        // getTypeCode
        public final String getTypeCode()
        {
            return ((this.type == null) ? "" : this.type.tcode());
        }

        // getTypeSig
        public final String getTypeSig()
        {
            return ((this.type == null) ? "" : this.type.tsig());
        }

        // resolve
        void resolve( Unit uspec )
        {
            this.enterAttrs(Decl.Typedef.reservedAttrs);

            if (this.hasAttr(Attr.A_Encoded)) {
                ((Unit) this.parent).custHdr = true;
            }

            if (this.type == null) {
                return;
            }

            this.type.resolve(uspec, this.attrBool(Attr.A_Encoded));

            Type t = this.type;
            while (t instanceof Type.Declarator) {
                Node n = t.tspec().getRef().getNode();
                if (n == this) {
                    ses.msg.error(this.name, "circular typedef");
                    return;
                }
                if (!(n instanceof Typedef)) {
                    break;
                }
                t = ((Typedef) n).getType();
            }
            
            Decl.checkSig(this);
        }

        // sizeof
        public void sizeof( List<String> sL )
        {
            if (this.attrBool(Attr.A_Encoded)) {
                Unit unit = (Unit) this.parent;
                sL.add("E" + unit.getQualName() + ';' + this.name.text);
            }
            else {
                this.type.sizeof(sL);
            }
        }
    }
}
