package edu.uci.ics.asterix.translator;

import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import edu.uci.ics.asterix.aql.base.Clause;
import edu.uci.ics.asterix.aql.base.Expression;
import edu.uci.ics.asterix.aql.base.Statement;
import edu.uci.ics.asterix.aql.base.Statement.Kind;
import edu.uci.ics.asterix.aql.expression.BeginFeedStatement;
import edu.uci.ics.asterix.aql.expression.CallExpr;
import edu.uci.ics.asterix.aql.expression.ControlFeedStatement;
import edu.uci.ics.asterix.aql.expression.CreateIndexStatement;
import edu.uci.ics.asterix.aql.expression.DeleteStatement;
import edu.uci.ics.asterix.aql.expression.FLWOGRExpression;
import edu.uci.ics.asterix.aql.expression.FieldAccessor;
import edu.uci.ics.asterix.aql.expression.FieldBinding;
import edu.uci.ics.asterix.aql.expression.ForClause;
import edu.uci.ics.asterix.aql.expression.Identifier;
import edu.uci.ics.asterix.aql.expression.InsertStatement;
import edu.uci.ics.asterix.aql.expression.LiteralExpr;
import edu.uci.ics.asterix.aql.expression.LoadFromFileStatement;
import edu.uci.ics.asterix.aql.expression.Query;
import edu.uci.ics.asterix.aql.expression.RecordConstructor;
import edu.uci.ics.asterix.aql.expression.VariableExpr;
import edu.uci.ics.asterix.aql.expression.WhereClause;
import edu.uci.ics.asterix.aql.expression.WriteFromQueryResultStatement;
import edu.uci.ics.asterix.aql.expression.ControlFeedStatement.OperationType;
import edu.uci.ics.asterix.aql.literal.StringLiteral;
import edu.uci.ics.asterix.common.config.DatasetConfig.DatasetType;
import edu.uci.ics.asterix.common.config.DatasetConfig.IndexType;
import edu.uci.ics.asterix.metadata.IDatasetDetails;
import edu.uci.ics.asterix.metadata.MetadataException;
import edu.uci.ics.asterix.metadata.MetadataManager;
import edu.uci.ics.asterix.metadata.MetadataTransactionContext;
import edu.uci.ics.asterix.metadata.declared.AqlCompiledDatasetDecl;
import edu.uci.ics.asterix.metadata.declared.AqlCompiledMetadataDeclarations;
import edu.uci.ics.asterix.metadata.entities.Dataset;
import edu.uci.ics.asterix.metadata.entities.FeedDatasetDetails;
import edu.uci.ics.asterix.om.functions.AsterixFunction;
import edu.uci.ics.asterix.om.types.ARecordType;
import edu.uci.ics.asterix.om.types.IAType;
import edu.uci.ics.asterix.transaction.management.exception.ACIDException;
import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;

public class DmlTranslator extends AbstractAqlTranslator {

    private final MetadataTransactionContext mdTxnCtx;
    private final List<Statement> aqlStatements;
    private AqlCompiledMetadataDeclarations compiledDeclarations;
    private List<ICompiledDmlStatement> compiledDmlStatements;

    public DmlTranslator(MetadataTransactionContext mdTxnCtx, List<Statement> aqlStatements) {
        this.mdTxnCtx = mdTxnCtx;
        this.aqlStatements = aqlStatements;
    }

    public void translate() throws AlgebricksException, RemoteException, ACIDException, MetadataException {
        compiledDeclarations = compileMetadata(mdTxnCtx, aqlStatements, true);
        compiledDmlStatements = compileDmlStatements();
    }

    public AqlCompiledMetadataDeclarations getCompiledDeclarations() {
        return compiledDeclarations;
    }

    public List<ICompiledDmlStatement> getCompiledDmlStatements() {
        return compiledDmlStatements;
    }

    private List<ICompiledDmlStatement> compileDmlStatements() throws AlgebricksException {
        List<ICompiledDmlStatement> dmlStatements = new ArrayList<ICompiledDmlStatement>();
        for (Statement stmt : aqlStatements) {
            validateOperation(compiledDeclarations, stmt);
            switch (stmt.getKind()) {
                case LOAD_FROM_FILE: {
                    LoadFromFileStatement st1 = (LoadFromFileStatement) stmt;
                    CompiledLoadFromFileStatement cls = new CompiledLoadFromFileStatement(st1.getDatasetName()
                            .getValue(), st1.getAdapter(), st1.getProperties(), st1.dataIsAlreadySorted());
                    dmlStatements.add(cls);
                    break;
                }
                case WRITE_FROM_QUERY_RESULT: {
                    WriteFromQueryResultStatement st1 = (WriteFromQueryResultStatement) stmt;
                    CompiledWriteFromQueryResultStatement clfrqs = new CompiledWriteFromQueryResultStatement(st1
                            .getDatasetName().getValue(), st1.getQuery(), st1.getVarCounter());
                    dmlStatements.add(clfrqs);
                    break;
                }
                case CREATE_INDEX: {
                    CreateIndexStatement cis = (CreateIndexStatement) stmt;
                    if (cis.getNeedToCreate()) {
                        CompiledCreateIndexStatement ccis = new CompiledCreateIndexStatement(cis.getIndexName()
                                .getValue(), cis.getDatasetName().getValue(), cis.getFieldExprs(), cis.getIndexType());
                        dmlStatements.add(ccis);
                    }
                    break;
                }
                case INSERT: {
                    InsertStatement is = (InsertStatement) stmt;
                    CompiledInsertStatement clfrqs = new CompiledInsertStatement(is.getDatasetName().getValue(), is
                            .getQuery(), is.getVarCounter());
                    dmlStatements.add(clfrqs);
                    break;
                }
                case DELETE: {
                    DeleteStatement ds = (DeleteStatement) stmt;
                    CompiledDeleteStatement clfrqs = new CompiledDeleteStatement(ds.getVariableExpr(), ds
                            .getDatasetName(), ds.getCondition(), ds.getDieClause(), ds.getVarCounter(),
                            compiledDeclarations);
                    dmlStatements.add(clfrqs);
                    break;
                }

                case BEGIN_FEED: {
                    BeginFeedStatement bfs = (BeginFeedStatement) stmt;
                    CompiledBeginFeedStatement cbfs = new CompiledBeginFeedStatement(bfs.getDatasetName(), bfs
                            .getQuery(), bfs.getVarCounter());
                    dmlStatements.add(cbfs);
                    Dataset dataset;
                    try {
                        dataset = MetadataManager.INSTANCE.getDataset(mdTxnCtx,
                                compiledDeclarations.getDataverseName(), bfs.getDatasetName().getValue());
                    } catch (MetadataException me) {
                        throw new AlgebricksException(me);
                    }
                    IDatasetDetails datasetDetails = dataset.getDatasetDetails();
                    if (datasetDetails.getDatasetType() != DatasetType.FEED) {
                        throw new IllegalArgumentException("Dataset " + bfs.getDatasetName().getValue()
                                + " is not a feed dataset");
                    }
                    bfs.initialize((FeedDatasetDetails) datasetDetails);
                    cbfs.setQuery(bfs.getQuery());
                    break;
                }

                case CONTROL_FEED: {
                    ControlFeedStatement cfs = (ControlFeedStatement) stmt;
                    CompiledControlFeedStatement clcfs = new CompiledControlFeedStatement(cfs.getOperationType(), cfs
                            .getDatasetName(), cfs.getAlterAdapterConfParams());
                    dmlStatements.add(clcfs);
                    break;

                }
            }
        }
        return dmlStatements;
    }

    public static interface ICompiledDmlStatement {

        public abstract Kind getKind();
    }

    public static class CompiledCreateIndexStatement implements ICompiledDmlStatement {
        private String indexName;
        private String datasetName;
        private List<String> keyFields;
        private IndexType indexType;

        public CompiledCreateIndexStatement(String indexName, String datasetName, List<String> keyFields,
                IndexType indexType) {
            this.indexName = indexName;
            this.datasetName = datasetName;
            this.keyFields = keyFields;
            this.indexType = indexType;
        }

        public String getDatasetName() {
            return datasetName;
        }

        public String getIndexName() {
            return indexName;
        }

        public List<String> getKeyFields() {
            return keyFields;
        }

        public IndexType getIndexType() {
            return indexType;
        }

        @Override
        public Kind getKind() {
            return Kind.CREATE_INDEX;
        }
    }

    public static class CompiledLoadFromFileStatement implements ICompiledDmlStatement {
        private String datasetName;
        private boolean alreadySorted;
        private String adapter;
        private Map<String, String> properties;

        public CompiledLoadFromFileStatement(String datasetName, String adapter, Map<String, String> properties,
                boolean alreadySorted) {
            this.datasetName = datasetName;
            this.alreadySorted = alreadySorted;
            this.adapter = adapter;
            this.properties = properties;
        }

        public String getDatasetName() {
            return datasetName;
        }

        public boolean alreadySorted() {
            return alreadySorted;
        }

        public String getAdapter() {
            return adapter;
        }

        public Map<String, String> getProperties() {
            return properties;
        }

        @Override
        public Kind getKind() {
            return Kind.LOAD_FROM_FILE;
        }
    }

    public static class CompiledWriteFromQueryResultStatement implements ICompiledDmlStatement {

        private String datasetName;
        private Query query;
        private int varCounter;

        public CompiledWriteFromQueryResultStatement(String datasetName, Query query, int varCounter) {
            this.datasetName = datasetName;
            this.query = query;
            this.varCounter = varCounter;
        }

        public String getDatasetName() {
            return datasetName;
        }

        public int getVarCounter() {
            return varCounter;
        }

        public Query getQuery() {
            return query;
        }

        @Override
        public Kind getKind() {
            return Kind.WRITE_FROM_QUERY_RESULT;
        }

    }

    public static class CompiledInsertStatement implements ICompiledDmlStatement {
        private String datasetName;
        private Query query;
        private int varCounter;

        public CompiledInsertStatement(String datasetName, Query query, int varCounter) {
            this.datasetName = datasetName;
            this.query = query;
            this.varCounter = varCounter;
        }

        public String getDatasetName() {
            return datasetName;
        }

        public int getVarCounter() {
            return varCounter;
        }

        public Query getQuery() {
            return query;
        }

        @Override
        public Kind getKind() {
            return Kind.INSERT;
        }
    }

    public static class CompiledBeginFeedStatement implements ICompiledDmlStatement {
        private Identifier datasetName;
        private Query query;
        private int varCounter;

        public CompiledBeginFeedStatement(Identifier datasetName, Query query, int varCounter) {
            this.datasetName = datasetName;
            this.query = query;
            this.varCounter = varCounter;
        }

        public Identifier getDatasetName() {
            return datasetName;
        }

        public int getVarCounter() {
            return varCounter;
        }

        public Query getQuery() {
            return query;
        }

        public void setQuery(Query query) {
            this.query = query;
        }

        @Override
        public Kind getKind() {
            return Kind.BEGIN_FEED;
        }
    }

    public static class CompiledControlFeedStatement implements ICompiledDmlStatement {
        private Identifier datasetName;
        private OperationType operationType;
        private Query query;
        private int varCounter;
        private Map<String, String> alteredParams;

        public CompiledControlFeedStatement(OperationType operationType, Identifier datasetName,
                Map<String, String> alteredParams) {
            this.datasetName = datasetName;
            this.operationType = operationType;
            this.alteredParams = alteredParams;
        }

        public Identifier getDatasetName() {
            return datasetName;
        }

        public OperationType getOperationType() {
            return operationType;
        }

        public int getVarCounter() {
            return varCounter;
        }

        public Query getQuery() {
            return query;
        }

        @Override
        public Kind getKind() {
            return Kind.CONTROL_FEED;
        }

        public Map<String, String> getProperties() {
            return alteredParams;
        }

        public void setProperties(Map<String, String> properties) {
            this.alteredParams = properties;
        }
    }

    public static class CompiledDeleteStatement implements ICompiledDmlStatement {
        private VariableExpr var;
        private Identifier dataset;
        private Expression condition;
        private Clause dieClause;
        private int varCounter;
        private AqlCompiledMetadataDeclarations compiledDeclarations;

        public CompiledDeleteStatement(VariableExpr var, Identifier dataset, Expression condition, Clause dieClause,
                int varCounter, AqlCompiledMetadataDeclarations compiledDeclarations) {
            this.var = var;
            this.dataset = dataset;
            this.condition = condition;
            this.dieClause = dieClause;
            this.varCounter = varCounter;
            this.compiledDeclarations = compiledDeclarations;
        }

        public Identifier getDataset() {
            return dataset;
        }

        public String getDatasetName() {
            return dataset.getValue();
        }

        public int getVarCounter() {
            return varCounter;
        }

        public Expression getCondition() {
            return condition;
        }

        public Clause getDieClause() {
            return dieClause;
        }

        public Query getQuery() throws AlgebricksException {
            String datasetName = dataset.getValue();

            List<Expression> arguments = new ArrayList<Expression>();
            LiteralExpr argumentLiteral = new LiteralExpr(new StringLiteral(datasetName));
            arguments.add(argumentLiteral);

            CallExpr callExpression = new CallExpr(new AsterixFunction("dataset", 1), arguments);
            List<Clause> clauseList = new ArrayList<Clause>();
            Clause forClause = new ForClause(var, callExpression);
            clauseList.add(forClause);
            Clause whereClause = null;
            if (condition != null) {
                whereClause = new WhereClause(condition);
                clauseList.add(whereClause);
            }
            if (dieClause != null) {
                clauseList.add(dieClause);
            }

            AqlCompiledDatasetDecl aqlDataset = compiledDeclarations.findDataset(datasetName);
            if (aqlDataset == null) {
                throw new AlgebricksException("Unknown dataset " + datasetName);
            }
            String itemTypeName = aqlDataset.getItemTypeName();
            IAType itemType = compiledDeclarations.findType(itemTypeName);
            ARecordType recType = (ARecordType) itemType;
            String[] fieldNames = recType.getFieldNames();
            List<FieldBinding> fieldBindings = new ArrayList<FieldBinding>();
            for (int i = 0; i < fieldNames.length; i++) {
                FieldAccessor fa = new FieldAccessor(var, new Identifier(fieldNames[i]));
                FieldBinding fb = new FieldBinding(new LiteralExpr(new StringLiteral(fieldNames[i])), fa);
                fieldBindings.add(fb);
            }
            RecordConstructor rc = new RecordConstructor(fieldBindings);

            FLWOGRExpression flowgr = new FLWOGRExpression(clauseList, rc);
            Query query = new Query();
            query.setBody(flowgr);
            return query;
        }

        @Override
        public Kind getKind() {
            return Kind.DELETE;
        }

    }

}
