/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.hcatalog.cli.SemanticAnalysis;

import java.io.Serializable;
import java.util.List;

import org.apache.hadoop.hive.metastore.api.Database;
import org.apache.hadoop.hive.ql.exec.Task;
import org.apache.hadoop.hive.ql.metadata.Hive;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.metadata.Partition;
import org.apache.hadoop.hive.ql.metadata.Table;
import org.apache.hadoop.hive.ql.parse.ASTNode;
import org.apache.hadoop.hive.ql.parse.AbstractSemanticAnalyzerHook;
import org.apache.hadoop.hive.ql.parse.HiveParser;
import org.apache.hadoop.hive.ql.parse.HiveSemanticAnalyzerHookContext;
import org.apache.hadoop.hive.ql.parse.SemanticException;
import org.apache.hadoop.hive.ql.plan.AlterTableDesc;
import org.apache.hadoop.hive.ql.plan.DDLWork;
import org.apache.hadoop.hive.ql.plan.DescDatabaseDesc;
import org.apache.hadoop.hive.ql.plan.DescTableDesc;
import org.apache.hadoop.hive.ql.plan.DropDatabaseDesc;
import org.apache.hadoop.hive.ql.plan.DropTableDesc;
import org.apache.hadoop.hive.ql.plan.HiveOperation;
import org.apache.hadoop.hive.ql.plan.PartitionSpec;
import org.apache.hadoop.hive.ql.plan.ShowDatabasesDesc;
import org.apache.hadoop.hive.ql.plan.ShowPartitionsDesc;
import org.apache.hadoop.hive.ql.plan.ShowTableStatusDesc;
import org.apache.hadoop.hive.ql.plan.ShowTablesDesc;
import org.apache.hadoop.hive.ql.plan.SwitchDatabaseDesc;
import org.apache.hadoop.hive.ql.security.authorization.Privilege;
import org.apache.hcatalog.common.ErrorType;
import org.apache.hcatalog.common.HCatException;

public class HCatSemanticAnalyzer extends HCatSemanticAnalyzerBase {

    private AbstractSemanticAnalyzerHook hook;
    private ASTNode ast;


    @Override
    public ASTNode preAnalyze(HiveSemanticAnalyzerHookContext context, ASTNode ast)
        throws SemanticException {

        this.ast = ast;
        switch (ast.getToken().getType()) {

        // HCat wants to intercept following tokens and special-handle them.
        case HiveParser.TOK_CREATETABLE:
            hook = new CreateTableHook();
            return hook.preAnalyze(context, ast);

        case HiveParser.TOK_CREATEDATABASE:
            hook = new CreateDatabaseHook();
            return hook.preAnalyze(context, ast);

        case HiveParser.TOK_ALTERTABLE_PARTITION:
            if (((ASTNode) ast.getChild(1)).getToken().getType() == HiveParser.TOK_ALTERTABLE_FILEFORMAT) {
                return ast;
            } else if (((ASTNode) ast.getChild(1)).getToken().getType() == HiveParser.TOK_ALTERTABLE_ALTERPARTS_MERGEFILES) {
                // unsupported
                throw new SemanticException("Operation not supported.");
            } else {
                return ast;
            }

            // HCat will allow these operations to be performed.
            // Database DDL
        case HiveParser.TOK_SHOWDATABASES:
        case HiveParser.TOK_DROPDATABASE:
        case HiveParser.TOK_SWITCHDATABASE:
        case HiveParser.TOK_DESCDATABASE:
        case HiveParser.TOK_ALTERDATABASE_PROPERTIES:

            // Index DDL
        case HiveParser.TOK_ALTERINDEX_PROPERTIES:
        case HiveParser.TOK_CREATEINDEX:
        case HiveParser.TOK_DROPINDEX:
        case HiveParser.TOK_SHOWINDEXES:

            // View DDL
            // "alter view add partition" does not work because of the nature of implementation
            // of the DDL in hive. Hive will internally invoke another Driver on the select statement,
            // and HCat does not let "select" statement through. I cannot find a way to get around it
            // without modifying hive code. So just leave it unsupported.
            //case HiveParser.TOK_ALTERVIEW_ADDPARTS:
        case HiveParser.TOK_ALTERVIEW_DROPPARTS:
        case HiveParser.TOK_ALTERVIEW_PROPERTIES:
        case HiveParser.TOK_ALTERVIEW_RENAME:
        case HiveParser.TOK_CREATEVIEW:
        case HiveParser.TOK_DROPVIEW:

            // Authorization DDL
        case HiveParser.TOK_CREATEROLE:
        case HiveParser.TOK_DROPROLE:
        case HiveParser.TOK_GRANT_ROLE:
        case HiveParser.TOK_GRANT_WITH_OPTION:
        case HiveParser.TOK_GRANT:
        case HiveParser.TOK_REVOKE_ROLE:
        case HiveParser.TOK_REVOKE:
        case HiveParser.TOK_SHOW_GRANT:
        case HiveParser.TOK_SHOW_ROLE_GRANT:

            // Misc DDL
        case HiveParser.TOK_LOCKTABLE:
        case HiveParser.TOK_UNLOCKTABLE:
        case HiveParser.TOK_SHOWLOCKS:
        case HiveParser.TOK_DESCFUNCTION:
        case HiveParser.TOK_SHOWFUNCTIONS:
        case HiveParser.TOK_EXPLAIN:

            // Table DDL
        case HiveParser.TOK_ALTERTABLE_ADDPARTS:
        case HiveParser.TOK_ALTERTABLE_ADDCOLS:
        case HiveParser.TOK_ALTERTABLE_CHANGECOL_AFTER_POSITION:
        case HiveParser.TOK_ALTERTABLE_SERDEPROPERTIES:
        case HiveParser.TOK_ALTERTABLE_CLUSTER_SORT:
        case HiveParser.TOK_ALTERTABLE_DROPPARTS:
        case HiveParser.TOK_ALTERTABLE_PROPERTIES:
        case HiveParser.TOK_ALTERTABLE_RENAME:
        case HiveParser.TOK_ALTERTABLE_RENAMECOL:
        case HiveParser.TOK_ALTERTABLE_REPLACECOLS:
        case HiveParser.TOK_ALTERTABLE_SERIALIZER:
        case HiveParser.TOK_ALTERTABLE_TOUCH:
        case HiveParser.TOK_DESCTABLE:
        case HiveParser.TOK_DROPTABLE:
        case HiveParser.TOK_SHOW_TABLESTATUS:
        case HiveParser.TOK_SHOWPARTITIONS:
        case HiveParser.TOK_SHOWTABLES:
            return ast;

        // In all other cases, throw an exception. Its a white-list of allowed operations.
        default:
            throw new SemanticException("Operation not supported.");

        }
    }

    @Override
    public void postAnalyze(HiveSemanticAnalyzerHookContext context,
                            List<Task<? extends Serializable>> rootTasks) throws SemanticException {

        try {

            switch (ast.getToken().getType()) {

            case HiveParser.TOK_CREATETABLE:
            case HiveParser.TOK_CREATEDATABASE:
            case HiveParser.TOK_ALTERTABLE_PARTITION:

                // HCat will allow these operations to be performed.
                // Database DDL
            case HiveParser.TOK_SHOWDATABASES:
            case HiveParser.TOK_DROPDATABASE:
            case HiveParser.TOK_SWITCHDATABASE:
            case HiveParser.TOK_DESCDATABASE:
            case HiveParser.TOK_ALTERDATABASE_PROPERTIES:

                // Index DDL
            case HiveParser.TOK_ALTERINDEX_PROPERTIES:
            case HiveParser.TOK_CREATEINDEX:
            case HiveParser.TOK_DROPINDEX:
            case HiveParser.TOK_SHOWINDEXES:

                // View DDL
                //case HiveParser.TOK_ALTERVIEW_ADDPARTS:
            case HiveParser.TOK_ALTERVIEW_DROPPARTS:
            case HiveParser.TOK_ALTERVIEW_PROPERTIES:
            case HiveParser.TOK_ALTERVIEW_RENAME:
            case HiveParser.TOK_CREATEVIEW:
            case HiveParser.TOK_DROPVIEW:

                // Authorization DDL
            case HiveParser.TOK_CREATEROLE:
            case HiveParser.TOK_DROPROLE:
            case HiveParser.TOK_GRANT_ROLE:
            case HiveParser.TOK_GRANT_WITH_OPTION:
            case HiveParser.TOK_GRANT:
            case HiveParser.TOK_REVOKE_ROLE:
            case HiveParser.TOK_REVOKE:
            case HiveParser.TOK_SHOW_GRANT:
            case HiveParser.TOK_SHOW_ROLE_GRANT:

                // Misc DDL
            case HiveParser.TOK_LOCKTABLE:
            case HiveParser.TOK_UNLOCKTABLE:
            case HiveParser.TOK_SHOWLOCKS:
            case HiveParser.TOK_DESCFUNCTION:
            case HiveParser.TOK_SHOWFUNCTIONS:
            case HiveParser.TOK_EXPLAIN:

                // Table DDL
            case HiveParser.TOK_ALTERTABLE_ADDPARTS:
            case HiveParser.TOK_ALTERTABLE_ADDCOLS:
            case HiveParser.TOK_ALTERTABLE_CHANGECOL_AFTER_POSITION:
            case HiveParser.TOK_ALTERTABLE_SERDEPROPERTIES:
            case HiveParser.TOK_ALTERTABLE_CLUSTER_SORT:
            case HiveParser.TOK_ALTERTABLE_DROPPARTS:
            case HiveParser.TOK_ALTERTABLE_PROPERTIES:
            case HiveParser.TOK_ALTERTABLE_RENAME:
            case HiveParser.TOK_ALTERTABLE_RENAMECOL:
            case HiveParser.TOK_ALTERTABLE_REPLACECOLS:
            case HiveParser.TOK_ALTERTABLE_SERIALIZER:
            case HiveParser.TOK_ALTERTABLE_TOUCH:
            case HiveParser.TOK_DESCTABLE:
            case HiveParser.TOK_DROPTABLE:
            case HiveParser.TOK_SHOW_TABLESTATUS:
            case HiveParser.TOK_SHOWPARTITIONS:
            case HiveParser.TOK_SHOWTABLES:
                break;

            default:
                throw new HCatException(ErrorType.ERROR_INTERNAL_EXCEPTION, "Unexpected token: " + ast.getToken());
            }

            authorizeDDL(context, rootTasks);

        } catch (HCatException e) {
            throw new SemanticException(e);
        } catch (HiveException e) {
            throw new SemanticException(e);
        }

        if (hook != null) {
            hook.postAnalyze(context, rootTasks);
        }
    }

    private String extractTableName(String compoundName) {
        /*
        * the table name can potentially be a dot-format one with column names
        * specified as part of the table name. e.g. a.b.c where b is a column in
        * a and c is a field of the object/column b etc. For authorization
        * purposes, we should use only the first part of the dotted name format.
        *
        */

        String[] words = compoundName.split("\\.");
        return words[0];
    }

    @Override
    protected void authorizeDDLWork(HiveSemanticAnalyzerHookContext cntxt, Hive hive, DDLWork work)
        throws HiveException {
        // DB opereations, none of them are enforced by Hive right now.

        ShowDatabasesDesc showDatabases = work.getShowDatabasesDesc();
        if (showDatabases != null) {
            authorize(HiveOperation.SHOWDATABASES.getInputRequiredPrivileges(),
                HiveOperation.SHOWDATABASES.getOutputRequiredPrivileges());
        }

        DropDatabaseDesc dropDb = work.getDropDatabaseDesc();
        if (dropDb != null) {
            Database db = cntxt.getHive().getDatabase(dropDb.getDatabaseName());
            authorize(db, Privilege.DROP);
        }

        DescDatabaseDesc descDb = work.getDescDatabaseDesc();
        if (descDb != null) {
            Database db = cntxt.getHive().getDatabase(descDb.getDatabaseName());
            authorize(db, Privilege.SELECT);
        }

        SwitchDatabaseDesc switchDb = work.getSwitchDatabaseDesc();
        if (switchDb != null) {
            Database db = cntxt.getHive().getDatabase(switchDb.getDatabaseName());
            authorize(db, Privilege.SELECT);
        }

        ShowTablesDesc showTables = work.getShowTblsDesc();
        if (showTables != null) {
            String dbName = showTables.getDbName() == null ? cntxt.getHive().getCurrentDatabase()
                : showTables.getDbName();
            authorize(cntxt.getHive().getDatabase(dbName), Privilege.SELECT);
        }

        ShowTableStatusDesc showTableStatus = work.getShowTblStatusDesc();
        if (showTableStatus != null) {
            String dbName = showTableStatus.getDbName() == null ? cntxt.getHive().getCurrentDatabase()
                : showTableStatus.getDbName();
            authorize(cntxt.getHive().getDatabase(dbName), Privilege.SELECT);
        }

        // TODO: add alter database support in HCat

        // Table operations.

        DropTableDesc dropTable = work.getDropTblDesc();
        if (dropTable != null) {
            if (dropTable.getPartSpecs() == null) {
                // drop table is already enforced by Hive. We only check for table level location even if the
                // table is partitioned.
            } else {
                //this is actually a ALTER TABLE DROP PARITITION statement
                for (PartitionSpec partSpec : dropTable.getPartSpecs()) {
                    // partitions are not added as write entries in drop partitions in Hive
                    Table table = hive.getTable(hive.getCurrentDatabase(), dropTable.getTableName());
                    List<Partition> partitions = null;
                    try {
                        partitions = hive.getPartitionsByFilter(table, partSpec.toString());
                    } catch (Exception e) {
                        throw new HiveException(e);
                    }

                    for (Partition part : partitions) {
                        authorize(part, Privilege.DROP);
                    }
                }
            }
        }

        AlterTableDesc alterTable = work.getAlterTblDesc();
        if (alterTable != null) {
            Table table = hive.getTable(hive.getCurrentDatabase(), alterTable.getOldName(), false);

            Partition part = null;
            if (alterTable.getPartSpec() != null) {
                part = hive.getPartition(table, alterTable.getPartSpec(), false);
            }

            String newLocation = alterTable.getNewLocation();

            /* Hcat requires ALTER_DATA privileges for ALTER TABLE LOCATION statements
            * for the old table/partition location and the new location.
            */
            if (alterTable.getOp() == AlterTableDesc.AlterTableTypes.ALTERLOCATION) {
                if (part != null) {
                    authorize(part, Privilege.ALTER_DATA); // authorize for the old
                    // location, and new location
                    part.setLocation(newLocation);
                    authorize(part, Privilege.ALTER_DATA);
                } else {
                    authorize(table, Privilege.ALTER_DATA); // authorize for the old
                    // location, and new location
                    table.getTTable().getSd().setLocation(newLocation);
                    authorize(table, Privilege.ALTER_DATA);
                }
            }
            //other alter operations are already supported by Hive
        }

        // we should be careful when authorizing table based on just the
        // table name. If columns have separate authorization domain, it
        // must be honored
        DescTableDesc descTable = work.getDescTblDesc();
        if (descTable != null) {
            String tableName = extractTableName(descTable.getTableName());
            authorizeTable(cntxt.getHive(), tableName, Privilege.SELECT);
        }

        ShowPartitionsDesc showParts = work.getShowPartsDesc();
        if (showParts != null) {
            String tableName = extractTableName(showParts.getTabName());
            authorizeTable(cntxt.getHive(), tableName, Privilege.SELECT);
        }
    }
}
