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

#pragma once

#include <map>
#include <string>
#include <boost/function.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <rapidjson/fwd.h>

#include "common/status.h"
#include "kudu/util/web_callback_registry.h"
#include "thirdparty/squeasel/squeasel.h"
#include "util/metrics-fwd.h"
#include "util/network-util.h"
#include "util/openssl-util.h"

namespace impala {

/// Supported HTTP content types
enum ContentType {
  /// Corresponds to text/html content-type and used for rendering HTML webpages.
  HTML,
  /// Following two are used for rendering text-only pages and correspond to text/plain
  /// and application/json content-types respectively. JSON type additionally pretty
  /// prints the underlying JSON content. They are primarily used for debugging and for
  /// integration with third-party tools that can consume the text format easily.
  PLAIN,
  JSON
};

/// Wrapper class for the Squeasel web server library. Clients may register callback
/// methods which produce Json documents which are rendered via a template file to either
/// HTML or text.
///
/// Apache Knox Integration
/// -----------------------
/// In order to be compatible with the Knox 'impalaui' service definition, there are a few
/// requirements that template files served by this webserver have to conform to:
/// - Any relative links to pages on this server must be proceeded by
///   {{ __common__.host-url }} so that they can be made into absolute urls when Knox
///   proxying is being used.
/// - Any forms must contain {{>www/form-hidden-inputs.tmpl}}, which adds some hidden
///   fields when Knox proxying is being used.
/// - Any relative urls that are accessed via javascript should be constructed with the
///   make_url() function in common-header.tmpl.
/// See: https://github.com/apache/knox/tree/master/gateway-service-definitions/
///     src/main/resources/services/impalaui/1.0.0
class Webserver {
 public:
  using ArgumentMap = kudu::WebCallbackRegistry::ArgumentMap;
  using WebRequest = kudu::WebCallbackRegistry::WebRequest;
  using HttpStatusCode = kudu::HttpStatusCode;

  typedef boost::function<void (const WebRequest& req, rapidjson::Document* json)>
      UrlCallback;
  typedef boost::function<void (const WebRequest& req, std::stringstream* output,
      HttpStatusCode* response)> RawUrlCallback;

  /// Any callback may add a member to their Json output with key ENABLE_RAW_HTML_KEY;
  /// this causes the result of the template rendering process to be sent to the browser
  /// as text, not HTML.
  static const char* ENABLE_RAW_HTML_KEY;

  /// Any callback may add a member to their Json output with key ENABLE_PLAIN_JSON_KEY;
  /// this causes the result of the template rendering process to be sent to the browser
  /// as pretty printed JSON plain text.
  static const char* ENABLE_PLAIN_JSON_KEY;

  /// Using this constructor, the webserver will bind to 'interface', or all available
  /// interfaces if not specified.
  Webserver(const std::string& interface, const int port, MetricGroup* metrics);

  /// Uses FLAGS_webserver_{port, interface}
  Webserver(MetricGroup* metrics);

  ~Webserver();

  /// Starts a webserver on the port passed to the constructor. The webserver runs in a
  /// separate thread, so this call is non-blocking.
  Status Start();

  /// Stops the webserver synchronously.
  void Stop();

  /// Register a callback for a Url that produces a json document that will be rendered
  /// with the template at 'template_filename'. The URL 'path' should not include the
  /// http://hostname/ prefix. If is_on_nav_bar is true, the page will appear in the
  /// standard navigation bar rendered on all pages.
  //
  /// Only one callback may be registered per URL.
  //
  /// The path of the template file is relative to the webserver's document
  /// root.
  void RegisterUrlCallback(const std::string& path, const std::string& template_filename,
      const UrlCallback& callback, bool is_on_nav_bar);

  /// Register a 'raw' url callback that produces a bytestream as output. This should only
  /// be used for URLs that want to return binary data; non-HTML callbacks that want to
  /// produce text should use UrlCallback.
  void RegisterUrlCallback(const std::string& path, const RawUrlCallback& callback);

  /// True if serving all traffic over SSL, false otherwise
  bool IsSecure() const;

  /// Returns the URL to the webserver as a string.
  string url() { return url_; }
  string hostname() { return hostname_; }
  int port() { return http_address_.port; }

  /// Returns the appropriate MIME type for a given ContentType.
  static const std::string GetMimeType(const ContentType& content_type);

 private:
  /// Contains all information relevant to rendering one Url. Each Url has one callback
  /// that produces the output to render. The callback either produces a Json document
  /// which is rendered via a template file, or it produces an HTML string that is embedded
  /// directly into the output.
  class UrlHandler {
   public:
    UrlHandler(const UrlCallback& cb, const std::string& template_filename,
        bool is_on_nav_bar)
        : is_on_nav_bar_(is_on_nav_bar), use_templates_(true), template_callback_(cb),
          template_filename_(template_filename) { }

    UrlHandler(const RawUrlCallback& cb)
        : is_on_nav_bar_(false), use_templates_(false),
          raw_callback_(cb) { }

    bool is_on_nav_bar() const { return is_on_nav_bar_; }
    bool use_templates() const { return use_templates_; }
    const UrlCallback& callback() const { return template_callback_; }
    const RawUrlCallback& raw_callback() const { return raw_callback_; }
    const std::string& template_filename() const { return template_filename_; }

   private:
    /// If true, the page appears in the navigation bar.
    bool is_on_nav_bar_;

    /// If true, use the template rendering callback, otherwise the 'raw' callback is
    /// used.
    bool use_templates_;

    /// Callback to produce a Json document to render via a template.
    UrlCallback template_callback_;

    /// Callback to produce a raw bytestream.
    RawUrlCallback raw_callback_;

    /// Path to the file that contains the template to render, relative to the webserver's
    /// document root.
    std::string template_filename_;
  };

  /// Sets the values of 'url_' and 'hostname_'.
  void Init();

  /// Squeasel callback for log events. Returns squeasel success code.
  static int LogMessageCallbackStatic(const struct sq_connection* connection,
      const char* message);

  /// Squeasel callback for HTTP request events. Static so that it can act as a function
  /// pointer, and then call the next method. Returns squeasel success code.
  static sq_callback_result_t BeginRequestCallbackStatic(
      struct sq_connection* connection);

  /// Dispatch point for all incoming requests. Returns squeasel success code.
  sq_callback_result_t BeginRequestCallback(struct sq_connection* connection,
      struct sq_request_info* request_info);

  // Handle SPNEGO authentication for this request. Returns SQ_CONTINUE_HANDLING
  // if authentication was successful, otherwise responds to the request and
  // returns SQ_HANDLED_OK.
  sq_callback_result_t HandleSpnego(struct sq_connection* connection,
      struct sq_request_info* request_info, std::vector<std::string>* response_headers);

  /// Renders URLs through the Mustache templating library.
  /// - Default ContentType is HTML.
  /// - Argument 'raw' renders the page with PLAIN ContentType.
  /// - Argument 'json' renders the page with JSON ContentType. The underlying JSON is
  ///   pretty-printed.
  void RenderUrlWithTemplate(const struct sq_connection* connection,
      const WebRequest& arguments, const UrlHandler& url_handler,
      std::stringstream* output, ContentType* content_type);

  /// Called when an error is encountered, e.g. when a handler for a URI cannot be found.
  void ErrorHandler(const WebRequest& req, rapidjson::Document* document);

  /// Builds a map of argument name to argument value from a typical URL argument
  /// string (that is, "key1=value1&key2=value2.."). If no value is given for a
  /// key, it is entered into the map as (key, "").
  void BuildArgumentMap(const std::string& args, ArgumentMap* output);

  /// Adds a __common__ object to document with common data that every webpage might want
  /// to read (e.g. the names of links to write to the navbar).
  void GetCommonJson(rapidjson::Document* document,
      const struct sq_connection* connection, const WebRequest& req);

  /// Lock guarding the path_handlers_ map
  boost::shared_mutex url_handlers_lock_;

  /// Map of path to a UrlHandler containing a list of handlers for that
  /// path. More than one handler may register itself with a path so that many
  /// components may contribute to a single page.
  typedef std::map<std::string, UrlHandler> UrlHandlerMap;
  UrlHandlerMap url_handlers_;

  /// The address of the interface on which to run this webserver.
  TNetworkAddress http_address_;

  /// Formatted string representing 'http_address_'.
  std::string url_;

  /// The resolved hostname from 'http_address_'.
  std::string hostname_;

  /// Handle to Squeasel context; owned and freed by Squeasel internally
  struct sq_context* context_;

  /// Catch-all handler for error messages
  UrlHandler error_handler_;

  /// Used to generate and verify signatures for cookies.
  AuthenticationHash hash_;

  /// If true and SPNEGO is in use, cookies will be used for authentication.
  bool use_cookies_;

  /// If 'FLAGS_webserver_require_spnego' is true, metrics for the number of successful
  /// and failed Negotiate auth attempts.
  IntCounter* total_negotiate_auth_success_ = nullptr;
  IntCounter* total_negotiate_auth_failure_ = nullptr;

  /// If 'use_cookies_' is true, metrics for the number of successful and failed cookie
  /// auth attempts.
  IntCounter* total_cookie_auth_success_ = nullptr;
  IntCounter* total_cookie_auth_failure_ = nullptr;
};

}
