/*******************************************************************************
 * Copyright (c) 2008, 2021 SAP AG.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *    SAP AG - initial API and implementation
 *******************************************************************************/
package org.eclipse.mat.inspections;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.URL;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.mat.SnapshotException;
import org.eclipse.mat.internal.Messages;
import org.eclipse.mat.query.Bytes;
import org.eclipse.mat.query.Column;
import org.eclipse.mat.query.IContextObject;
import org.eclipse.mat.query.IContextObjectSet;
import org.eclipse.mat.query.IDecorator;
import org.eclipse.mat.query.IIconProvider;
import org.eclipse.mat.query.IQuery;
import org.eclipse.mat.query.IResultTable;
import org.eclipse.mat.query.IResultTree;
import org.eclipse.mat.query.ResultMetaData;
import org.eclipse.mat.query.annotations.Argument;
import org.eclipse.mat.query.annotations.CommandName;
import org.eclipse.mat.query.annotations.HelpUrl;
import org.eclipse.mat.query.annotations.Icon;
import org.eclipse.mat.query.annotations.Usage;
import org.eclipse.mat.query.results.TextResult;
import org.eclipse.mat.snapshot.IOQLQuery;
import org.eclipse.mat.snapshot.ISnapshot;
import org.eclipse.mat.snapshot.OQL;
import org.eclipse.mat.snapshot.SnapshotFactory;
import org.eclipse.mat.snapshot.model.GCRootInfo;
import org.eclipse.mat.snapshot.model.IArray;
import org.eclipse.mat.snapshot.model.IClass;
import org.eclipse.mat.snapshot.model.IClassLoader;
import org.eclipse.mat.snapshot.model.IObject;
import org.eclipse.mat.snapshot.model.ObjectReference;
import org.eclipse.mat.snapshot.query.Icons;
import org.eclipse.mat.snapshot.query.ObjectListResult;
import org.eclipse.mat.util.IProgressListener;

@CommandName("oql")
@Icon("/META-INF/icons/oql.gif")
@Usage("oql \"select * from ...\"")
@HelpUrl("/org.eclipse.mat.ui.help/tasks/queryingheapobjects.html")
public class OQLQuery implements IQuery
{
    @Argument
    public ISnapshot snapshot;

    @Argument(flag = Argument.UNFLAGGED)
    public String queryString = "select * from ..."; //$NON-NLS-1$

    @Argument(isMandatory = false)
    public List<IContextObject> contexts;

    public IOQLQuery.Result execute(IProgressListener listener) throws Exception
    {

        try
        {
            String oqlQuery = queryString;
            if (contexts != null)
            {
                // Merge the query with the objects 
                Pattern p = Pattern.compile("select (.*) from( .*)?", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
                Matcher m = p.matcher(oqlQuery);
                String rep;
                if (m.find())
                    rep = m.group(1);
                else
                    rep = "*"; //$NON-NLS-1$
                StringBuilder sb = new StringBuilder();
                for (IContextObject c : contexts)
                {
                    if (c instanceof IContextObjectSet)
                    {
                        IContextObjectSet context = (IContextObjectSet)c;

                        String q2 = context.getOQL();
                        if (q2 != null)
                            OQL.union(sb, q2.replaceFirst("\\*", rep)); //$NON-NLS-1$
                        else
                        {
                            int o[] = context.getObjectIds();
                            if (o.length >= 1)
                            {
                                q2 = OQL.forObjectIds(context.getObjectIds());
                                OQL.union(sb, q2.replaceFirst("\\*", rep)); //$NON-NLS-1$
                            }
                        }
                    }
                    else
                    {
                        if (c.getObjectId() >= 0)
                        {
                            String q3 = OQL.forObjectId(c.getObjectId());
                            OQL.union(sb, q3.replaceFirst("\\*", rep)); //$NON-NLS-1$
                        }
                    }
                    if (sb.length() > 1000)
                        break;
                }
                if (sb.length() > 0)
                {
                    queryString = sb.toString();
                    if (sb.length() > 1000)
                        throw new SnapshotException(Messages.OQLQuery_TooManyObjects);
                }
            }
            IOQLQuery query = SnapshotFactory.createQuery(queryString);
            Object result = query.execute(snapshot, listener);

            if (result == null)
            {
                return new OQLTextResult(Messages.OQLQuery_NoResult + "\n\n" + query, queryString); //$NON-NLS-1$
            }
            else if (result instanceof IOQLQuery.Result)
            {
                return (IOQLQuery.Result) result;
            }
            else if (result instanceof int[])
            {
                return new ObjectListResultImpl(snapshot, queryString, (int[]) result);
            }
            else if (result instanceof List<?>)
            {
                return new ObjectTableResultImpl(snapshot, queryString, (List<?>) result);
            }
            else
            {
                return new OQLTextResult(String.valueOf(result), queryString);
            }
        }
        catch (IProgressListener.OperationCanceledException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            StringBuilder buf = new StringBuilder(256);
            buf.append(Messages.OQLQuery_ExecutedQuery + "\n"); //$NON-NLS-1$
            buf.append(queryString);

            Throwable t = null;
            if (e instanceof SnapshotException)
            {
                buf.append("\n\n" + Messages.OQLQuery_ProblemReported + "\n"); //$NON-NLS-1$ //$NON-NLS-2$
                buf.append(e.getMessage());
                t = e.getCause();
            }
            else
            {
                t = e;
            }

            if (t != null)
            {
                buf.append("\n\n"); //$NON-NLS-1$
                StringWriter w = new StringWriter();
                PrintWriter o = new PrintWriter(w);
                t.printStackTrace(o);
                o.flush();

                buf.append(w.toString());
            }

            return new OQLTextResult(buf.toString(), queryString);
        }
    }

    static class ObjectListResultImpl extends ObjectListResult.Outbound implements IOQLQuery.Result,
                    IResultTree
    {
        String queryString;

        public ObjectListResultImpl(ISnapshot snapshot, String queryString, int[] objectIds)
        {
            super(snapshot, objectIds);
            this.queryString = queryString;
        }

        public String getOQLQuery()
        {
            return queryString;
        }
    }

    static class OQLTextResult extends TextResult implements IOQLQuery.Result
    {
        String queryString;

        public OQLTextResult(String text, String queryString)
        {
            super(text);
            this.queryString = queryString;
        }

        public String getOQLQuery()
        {
            return queryString;
        }
    }


    static class ObjectTableResultImpl implements IOQLQuery.Result,
    IResultTable, IDecorator, IIconProvider
    {
        String queryString;
        List<?>objs;
        boolean hasIObjects;

        public ObjectTableResultImpl(ISnapshot snapshot, String queryString, List<?>objs)
        {
            this.queryString = queryString;
            this.objs = objs;
            for (Object o : objs)
            {
                if (o instanceof ObjectReference || o instanceof IObject)
                {
                    hasIObjects = true;
                    break;
                }
            }
        }

        public String getOQLQuery()
        {
            return queryString;
        }

        @Override
        public ResultMetaData getResultMetaData()
        {
            return null;
        }

        @Override
        public Column[] getColumns()
        {
            if (hasIObjects)
                return new Column[] { new Column(Messages.Column_ClassName).decorator(this), //
                                new Column(Messages.Column_ShallowHeap, Bytes.class).noTotals(), //
                                new Column(Messages.Column_RetainedHeap, Bytes.class).noTotals() };
            else
                return new Column[] { new Column(Messages.OQLQuery_Column_Value) };
        }

        @Override
        public Object getColumnValue(Object row, int columnIndex)
        {
            int rw = (Integer)row;
            //Object o;
            switch (columnIndex)
            {
                case 0:
                    Object o = objs.get(rw);
                    if (o instanceof ObjectReference)
                    {
                        try
                        {
                            return ((ObjectReference)o).getObject().getDisplayName();
                        }
                        catch (SnapshotException e)
                        {
                            return new IllegalStateException(e);
                        }
                    }
                    else if (o instanceof IObject)
                        return ((IObject)o).getDisplayName();
                    else if (o != null)
                        return o.toString();
                    else
                        return null;
                case 1:
                    if (!hasIObjects)
                        throw new IllegalArgumentException();
                    o = objs.get(rw);
                    if (o instanceof ObjectReference)
                    {
                        try
                        {
                            return ((ObjectReference)o).getObject().getUsedHeapSize();
                        }
                        catch (SnapshotException e)
                        {
                            return new IllegalStateException(e);
                        }
                    }
                    else if (o instanceof IObject)
                        return ((IObject)o).getUsedHeapSize();
                    else
                        return null;
                case 2:
                    if (!hasIObjects)
                        throw new IllegalArgumentException();
                    o = objs.get(rw);
                    if (o instanceof ObjectReference)
                    {
                        try
                        {
                            return ((ObjectReference)o).getObject().getRetainedHeapSize();
                        }
                        catch (SnapshotException e)
                        {
                            return new IllegalStateException(e);
                        }
                    }
                    else if (o instanceof IObject)
                        return ((IObject)o).getRetainedHeapSize();
                    else
                        return null;
                default:
                    throw new IllegalArgumentException(row.toString());
            }
        }

        @Override
        public IContextObject getContext(Object row)
        {
            if (!hasIObjects)
                return null;
            int rw = (Integer)row;
            return new IContextObjectSet() {

                @Override
                public int getObjectId()
                {
                    Object o = objs.get(rw);
                    if (o instanceof ObjectReference)
                    try
                    {
                            return ((ObjectReference)o).getObjectId();
                    }
                    catch (SnapshotException e)
                    {
                        return -1;
                    }
                    else if (o instanceof IObject)
                    {
                        try
                        {
                            return ((IObject)o).getObjectId();
                        }
                        catch (RuntimeException e)
                        {
                            if (e.getCause() instanceof SnapshotException)
                                return -1;
                            else
                                throw e;
                        }
                    }
                    return -1;
                }

                @Override
                public int[] getObjectIds()
                {
                    int objId = getObjectId();
                    if (objId == -1)
                        return new int[0];
                    else
                        return new int[] {objId};
                }

                @Override
                public String getOQL()
                {
                    Object o = objs.get(rw);
                    if (o instanceof ObjectReference)
                        return OQL.forAddress(((ObjectReference)o).getObjectAddress());
                    else if (o instanceof IObject)
                        return OQL.forAddress(((IObject)o).getObjectAddress());
                    else
                        return null;
                }
            };
        }

        @Override
        public int getRowCount()
        {
            return objs.size();
        }

        @Override
        public Object getRow(int rowId)
        {
            return Integer.valueOf(rowId);
        }

        @Override
        public String prefix(Object row)
        {
            return null;
        }

        @Override
        public String suffix(Object row)
        {
            if (!hasIObjects)
                return null;
            int rw = (Integer)row;
            Object o = objs.get(rw);
            if (o instanceof ObjectReference)
            {
                try
                {

                    GCRootInfo gc[] = ((ObjectReference) o).getObject().getGCRootInfo();
                    if (gc != null)
                        return GCRootInfo.getTypeSetAsString(gc);
                    else
                        return null;
                }
                catch (SnapshotException e)
                {
                    // $JL-EXC$
                }
                return Messages.OQLQuery_Unindexed;
            }
            else if (o instanceof IObject)
            {
                try
                {

                    GCRootInfo gc[] = ((IObject) o).getGCRootInfo();
                    if (gc != null)
                        return GCRootInfo.getTypeSetAsString(gc);
                    else
                        return null;
                }
                catch (SnapshotException e)
                {
                    // $JL-EXC$
                }
                return Messages.OQLQuery_Unindexed;
            }
            return null;
        }

        @Override
        public URL getIcon(Object row)
        {
            if (!hasIObjects)
                return null;
            int rw = (Integer)row;
            Object o = objs.get(rw);
            if (o instanceof ObjectReference || o instanceof IObject)
            {
                try
                {
                    IObject o2 = o instanceof IObject ? (IObject)o : ((ObjectReference) o).getObject();
                    try
                    {
                        int objectId = o2.getObjectId();
                        return Icons.forObject(o2.getSnapshot(), objectId);
                    }
                    catch (RuntimeException e)
                    {
                        if (!(e.getCause() instanceof SnapshotException))
                            throw e;
                    }

                    if (o2 instanceof IClassLoader)
                        return Icons.CLASSLOADER_INSTANCE;
                    else if (o2 instanceof IClass)
                        return Icons.CLASS_INSTANCE;
                    else if (o2 instanceof IArray)
                        return Icons.ARRAY_INSTANCE;
                    else
                        return Icons.OBJECT_INSTANCE;
                }
                catch (SnapshotException e)
                {

                }
            }
            return null;
        }
    }
}
