// 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.

#ifndef IMPALA_SERVICE_FRONTEND_H
#define IMPALA_SERVICE_FRONTEND_H

#include <jni.h>

#include "gen-cpp/ImpalaService.h"
#include "gen-cpp/ImpalaHiveServer2Service.h"
#include "gen-cpp/Frontend_types.h"
#include "gen-cpp/LineageGraph_types.h"
#include "common/status.h"

namespace impala {

/// The Frontend is a proxy for the Java-side JniFrontend class. The interface is a set of
/// wrapper methods for methods called over JNI.
/// TODO: Consider changing all methods to accept and return only Thrift structures so that
/// all go through exactly the same calling code.
class Frontend {
 public:
  /// Does all the work of initialising the JNI method stubs. If any method can't be found,
  /// or if there is any further exception, the constructor will terminate the process.
  Frontend();

  /// Request to update the Impalad catalog cache. The 'req' argument contains a pointer
  /// to a CatalogServer used for the FE to call NativeGetNextCatalogTopicItem() back to
  /// get the catalog objects iteratively. Returns a response that contains details such
  /// as the new max catalog version.
  Status UpdateCatalogCache(const TUpdateCatalogCacheRequest& req,
      TUpdateCatalogCacheResponse *resp);

  /// Request to update the Impalad frontend cluster membership snapshot of executors.
  /// The TUpdateExecutorMembershipRequest contains the latest set of executor nodes.
  Status UpdateExecutorMembership(const TUpdateExecutorMembershipRequest& req);

  /// Call FE to get explain plan
  Status GetExplainPlan(const TQueryCtx& query_ctx, std::string* explain_string);

  /// Call FE to get TExecRequest.
  Status GetExecRequest(const TQueryCtx& query_ctx, TExecRequest* result);

  /// Get the metrics from the catalog used by this frontend.
  Status GetCatalogMetrics(TGetCatalogMetricsResult* resp);

  /// Returns all matching table names, per Hive's "SHOW TABLES <pattern>". Each
  /// table name returned is unqualified.
  /// If pattern is NULL, match all tables otherwise match only those tables that
  /// match the pattern string. Patterns are "p1|p2|p3" where | denotes choice,
  /// and each pN may contain wildcards denoted by '*' which match all strings.
  /// The TSessionState parameter is used to filter results of metadata operations when
  /// authorization is enabled. If this is a user initiated request, it should
  /// be set to the user's current session. If this is an Impala internal request,
  /// the session should be set to NULL which will skip privilege checks returning all
  /// results.
  Status GetTableNames(const std::string& db, const std::string* pattern,
      const TSessionState* session, TGetTablesResult* table_names);

  /// Return all databases matching the optional argument 'pattern'.
  /// If pattern is NULL, match all databases otherwise match only those databases that
  /// match the pattern string. Patterns are "p1|p2|p3" where | denotes choice,
  /// and each pN may contain wildcards denoted by '*' which match all strings.
  /// The TSessionState parameter is used to filter results of metadata operations when
  /// authorization is enabled. If this is a user initiated request, it should
  /// be set to the user's current session. If this is an Impala internal request,
  /// the session should be set to NULL which will skip privilege checks returning all
  /// results.
  Status GetDbs(const std::string* pattern, const TSessionState* session,
      TGetDbsResult* dbs);

  /// Return all data sources matching the optional argument 'pattern'.
  /// If pattern is NULL, match all data source names otherwise match only those that
  /// match the pattern string. Patterns are "p1|p2|p3" where | denotes choice,
  /// and each pN may contain wildcards denoted by '*' which match all strings.
  Status GetDataSrcMetadata(const std::string* pattern, TGetDataSrcsResult* result);

  /// Call FE to get the table/column stats.
  Status GetStats(const TShowStatsParams& params, TResultSet* result);

  /// Call FE to get the privileges granted to a principal.
  Status GetPrincipalPrivileges(const TShowGrantPrincipalParams& params,
      TResultSet* result);

  /// Return all functions of 'category' that match the optional argument 'pattern'.
  /// If pattern is NULL match all functions, otherwise match only those functions that
  /// match the pattern string.
  /// The TSessionState parameter is used to filter results of metadata operations when
  /// authorization is enabled. If this is a user initiated request, it should
  /// be set to the user's current session. If this is an Impala internal request,
  /// the session should be set to NULL which will skip privilege checks returning all
  /// results.
  Status GetFunctions(TFunctionCategory::type fn_category, const std::string& db,
      const std::string* pattern, const TSessionState* session,
      TGetFunctionsResult* functions);

  /// Gets the Thrift representation of a Catalog object. The request is a TCatalogObject
  /// which has the desired TCatalogObjectType and name properly set.
  /// Returns OK if the operation was successful, otherwise a Status object with
  /// information on the error will be returned.
  Status GetCatalogObject(const TCatalogObject& request, TCatalogObject* response);

  /// Call FE to get the roles.
  Status ShowRoles(const TShowRolesParams& params, TShowRolesResult* result);

  /// Returns (in the output parameter) the result of a DESCRIBE DATABASE db command.
  /// This command retrieves db metadata, such as db location and comment.
  /// The metadata that is returned is controlled by setting the 'output_style' field.
  /// If set to FORMATTED|EXTENDED, all the database's properties are returned.
  Status DescribeDb(const TDescribeDbParams& params, TDescribeResult* response);

  /// Returns (in the output parameter) the result of a DESCRIBE table command. This
  /// command retrieves table metadata, such as the column definitions. The metadata
  /// that is returned is controlled by setting the 'output_style' field. If this
  /// field is set to MINIMAL, only the column definitions are returned. If set to
  /// FORMATTED|EXTENDED, extended metadata is returned (in addition to the column defs).
  /// This includes info about the table properties, SerDe properties, StorageDescriptor
  /// properties, and more.  The current user session is needed for privileges checks.
  Status DescribeTable(const TDescribeTableParams& params, const TSessionState& session,
      TDescribeResult* response);

  /// Returns (in the output parameter) a string containing the CREATE TABLE command that
  /// creates the table specified in the params.
  Status ShowCreateTable(const TTableName& table_name, std::string* response);

  /// Returns (in the output parameter) a string containing the CREATE FUNCTION command that
  /// creates the function specified in the params.
  Status ShowCreateFunction(const TGetFunctionsParams& params, std::string* response);

  /// Validate Hadoop config; requires FE
  Status ValidateSettings();

  /// Calls FE to execute HiveServer2 metadata operation.
  Status ExecHiveServer2MetadataOp(const TMetadataOpRequest& request,
      TResultSet* result);

  /// Returns all Hadoop configurations in key, value form in result.
  Status GetAllHadoopConfigs(TGetAllHadoopConfigsResponse* result);

  /// Returns (in the output parameter) the value for the given config. The returned Thrift
  /// struct will indicate if the value was null or not found by not setting its 'value'
  /// field.
  Status GetHadoopConfig(const TGetHadoopConfigRequest& request,
      TGetHadoopConfigResponse* response);

  /// Returns (in the output parameter) the list of groups for the given user.
  Status GetHadoopGroups(const TGetHadoopGroupsRequest& request,
      TGetHadoopGroupsResponse* response);

  /// Loads a single file or set of files into a table or partition. Saves the RPC
  /// response in the TLoadDataResp output parameter. Returns OK if the operation
  /// completed successfully.
  Status LoadData(const TLoadDataReq& load_data_request, TLoadDataResp* response);

  /// Aborts transaction with the given transaction id.
  Status AbortTransaction(int64_t transaction_id);

  /// Unregisters an already committed transaction.
  Status UnregisterTransaction(int64_t transaction_id);

  /// Returns true if the error returned by the FE was due to an AuthorizationException.
  static bool IsAuthorizationError(const Status& status);

  /// Sets the frontend's catalog in the ready state. This is only used for testing in
  /// conjunction with InProcessImpalaServer. This sets the frontend's catalog as
  /// ready, so can receive queries without needing a catalog server.
  void SetCatalogIsReady();

  /// Waits for the FE catalog to be initialized and ready to receive queries.
  /// There is no bound on the wait time.
  void WaitForCatalog();

  /// Call FE to get files info for a table or partition.
  Status GetTableFiles(const TShowFilesParams& params, TResultSet* result);

  /// Creates a thrift descriptor table for testing.
  Status BuildTestDescriptorTable(const TBuildTestDescriptorTableParams& params,
      TDescriptorTable* result);

  // Call FE post-query execution hook
  Status CallQueryCompleteHooks(const TQueryCompleteContext& context);

 private:
  jobject fe_;  // instance of org.apache.impala.service.JniFrontend
  jmethodID create_exec_request_id_;  // JniFrontend.createExecRequest()
  jmethodID get_explain_plan_id_;  // JniFrontend.getExplainPlan()
  jmethodID get_hadoop_config_id_;  // JniFrontend.getHadoopConfig(byte[])
  jmethodID get_hadoop_configs_id_;  // JniFrontend.getAllHadoopConfigs()
  jmethodID get_hadoop_groups_id_;  // JniFrontend.getHadoopGroups()
  jmethodID check_config_id_; // JniFrontend.checkConfiguration()
  jmethodID update_catalog_cache_id_; // JniFrontend.updateCatalogCache(byte[][])
  jmethodID update_membership_id_; // JniFrontend.updateMembership()
  jmethodID get_catalog_metrics_id_; // JniFrontend.getCatalogMetrics()
  jmethodID get_table_names_id_; // JniFrontend.getTableNames
  jmethodID describe_db_id_; // JniFrontend.describeDb
  jmethodID describe_table_id_; // JniFrontend.describeTable
  jmethodID show_create_table_id_; // JniFrontend.showCreateTable
  jmethodID get_dbs_id_; // JniFrontend.getDbs
  jmethodID get_data_src_metadata_id_; // JniFrontend.getDataSrcMetadata
  jmethodID get_stats_id_; // JniFrontend.getTableStats
  jmethodID get_functions_id_; // JniFrontend.getFunctions
  jmethodID get_catalog_object_id_; // JniFrontend.getCatalogObject
  jmethodID show_roles_id_; // JniFrontend.getRoles
  jmethodID get_principal_privileges_id_; // JniFrontend.getPrincipalPrivileges
  jmethodID exec_hs2_metadata_op_id_; // JniFrontend.execHiveServer2MetadataOp
  jmethodID load_table_data_id_; // JniFrontend.loadTableData
  jmethodID set_catalog_is_ready_id_; // JniFrontend.setCatalogIsReady
  jmethodID wait_for_catalog_id_; // JniFrontend.waitForCatalog
  jmethodID get_table_files_id_; // JniFrontend.getTableFiles
  jmethodID show_create_function_id_; // JniFrontend.showCreateFunction
  jmethodID call_query_complete_hooks_id_; // JniFrontend.callQueryCompleteHooks
  jmethodID abort_txn_; // JniFrontend.abortTransaction()
  jmethodID unregister_txn_; // JniFrontend.abortTransaction()

  // Only used for testing.
  jmethodID build_test_descriptor_table_id_; // JniFrontend.buildTestDescriptorTable()

  jmethodID fe_ctor_;
};

}

#endif
