// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef NET_TEST_EMBEDDED_TEST_SERVER_EMBEDDED_TEST_SERVER_H_
#define NET_TEST_EMBEDDED_TEST_SERVER_EMBEDDED_TEST_SERVER_H_

#include <map>
#include <string>
#include <vector>

#include "base/basictypes.h"
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/thread.h"
#include "base/threading/thread_checker.h"
#include "net/socket/tcp_listen_socket.h"
#include "url/gurl.h"

namespace base {
class FilePath;
}

namespace net {
namespace test_server {

class HttpConnection;
class HttpResponse;
struct HttpRequest;

// This class is required to be able to have composition instead of inheritance,
class HttpListenSocket : public TCPListenSocket {
 public:
  HttpListenSocket(const SocketDescriptor socket_descriptor,
                   StreamListenSocket::Delegate* delegate);
  ~HttpListenSocket() override;
  virtual void Listen();

  // Listen on the current IO thread. If the IO thread has changed since this
  // object is constructed, call |ListenOnIOThread| to make sure it listens on
  // the right thread. Otherwise must call |Listen| instead.
  void ListenOnIOThread();

 private:
  friend class EmbeddedTestServer;

  // Detaches the current from |thread_checker_|.
  void DetachFromThread();

  base::ThreadChecker thread_checker_;
};

// Class providing an HTTP server for testing purpose. This is a basic server
// providing only an essential subset of HTTP/1.1 protocol. Especially,
// it assumes that the request syntax is correct. It *does not* support
// a Chunked Transfer Encoding.
//
// The common use case for unit tests is below:
//
// void SetUp() {
//   test_server_.reset(new EmbeddedTestServer());
//   ASSERT_TRUE(test_server_.InitializeAndWaitUntilReady());
//   test_server_->RegisterRequestHandler(
//       base::Bind(&FooTest::HandleRequest, base::Unretained(this)));
// }
//
// scoped_ptr<HttpResponse> HandleRequest(const HttpRequest& request) {
//   GURL absolute_url = test_server_->GetURL(request.relative_url);
//   if (absolute_url.path() != "/test")
//     return scoped_ptr<HttpResponse>();
//
//   scoped_ptr<HttpResponse> http_response(new HttpResponse());
//   http_response->set_code(test_server::SUCCESS);
//   http_response->set_content("hello");
//   http_response->set_content_type("text/plain");
//   return http_response.Pass();
// }
//
// For a test that spawns another process such as browser_tests, it is
// suggested to call InitializeAndWaitUntilReady in SetUpOnMainThread after
// the process is spawned. If you have to do it before the process spawns,
// you need to stop the server's thread so that there is no no other
// threads running while spawning the process. To do so, please follow
// the following example:
//
// void SetUp() {
//   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
//   // EmbeddedTestServer spawns a thread to initialize socket.
//   // Stop the thread in preparation for fork and exec.
//   embedded_test_server()->StopThread();
//   ...
//   InProcessBrowserTest::SetUp();
// }
//
// void SetUpOnMainThread() {
//   embedded_test_server()->RestartThreadAndListen();
// }
//
class EmbeddedTestServer : public StreamListenSocket::Delegate {
 public:
  typedef base::Callback<scoped_ptr<HttpResponse>(
      const HttpRequest& request)> HandleRequestCallback;

  // Creates a http test server. InitializeAndWaitUntilReady() must be called
  // to start the server.
  EmbeddedTestServer();
  ~EmbeddedTestServer() override;

  // Initializes and waits until the server is ready to accept requests.
  bool InitializeAndWaitUntilReady() WARN_UNUSED_RESULT;

  // Shuts down the http server and waits until the shutdown is complete.
  bool ShutdownAndWaitUntilComplete() WARN_UNUSED_RESULT;

  // Checks if the server is started.
  bool Started() const {
    return listen_socket_.get() != NULL;
  }

  // Returns the base URL to the server, which looks like
  // http://127.0.0.1:<port>/, where <port> is the actual port number used by
  // the server.
  const GURL& base_url() const { return base_url_; }

  // Returns a URL to the server based on the given relative URL, which
  // should start with '/'. For example: GetURL("/path?query=foo") =>
  // http://127.0.0.1:<port>/path?query=foo.
  GURL GetURL(const std::string& relative_url) const;

  // Similar to the above method with the difference that it uses the supplied
  // |hostname| for the URL instead of 127.0.0.1. The hostname should be
  // resolved to 127.0.0.1.
  GURL GetURL(const std::string& hostname,
              const std::string& relative_url) const;

  // Returns the port number used by the server.
  uint16 port() const { return port_; }

  // Registers request handler which serves files from |directory|.
  // For instance, a request to "/foo.html" is served by "foo.html" under
  // |directory|. Files under sub directories are also handled in the same way
  // (i.e. "/foo/bar.html" is served by "foo/bar.html" under |directory|).
  void ServeFilesFromDirectory(const base::FilePath& directory);

  // The most general purpose method. Any request processing can be added using
  // this method. Takes ownership of the object. The |callback| is called
  // on UI thread.
  void RegisterRequestHandler(const HandleRequestCallback& callback);

  // Stops IO thread that handles http requests.
  void StopThread();

  // Restarts IO thread and listen on the socket.
  void RestartThreadAndListen();

 private:
  void StartThread();

  // Initializes and starts the server. If initialization succeeds, Starts()
  // will return true.
  void InitializeOnIOThread();
  void ListenOnIOThread();

  // Shuts down the server.
  void ShutdownOnIOThread();

  // Handles a request when it is parsed. It passes the request to registed
  // request handlers and sends a http response.
  void HandleRequest(HttpConnection* connection,
                     scoped_ptr<HttpRequest> request);

  // StreamListenSocket::Delegate overrides:
  void DidAccept(StreamListenSocket* server,
                 scoped_ptr<StreamListenSocket> connection) override;
  void DidRead(StreamListenSocket* connection,
               const char* data,
               int length) override;
  void DidClose(StreamListenSocket* connection) override;

  HttpConnection* FindConnection(StreamListenSocket* socket);

  // Posts a task to the |io_thread_| and waits for a reply.
  bool PostTaskToIOThreadAndWait(
      const base::Closure& closure) WARN_UNUSED_RESULT;

  scoped_ptr<base::Thread> io_thread_;

  scoped_ptr<HttpListenSocket> listen_socket_;
  uint16 port_;
  GURL base_url_;

  // Owns the HttpConnection objects.
  std::map<StreamListenSocket*, HttpConnection*> connections_;

  // Vector of registered request handlers.
  std::vector<HandleRequestCallback> request_handlers_;

  base::ThreadChecker thread_checker_;

  // Note: This should remain the last member so it'll be destroyed and
  // invalidate its weak pointers before any other members are destroyed.
  base::WeakPtrFactory<EmbeddedTestServer> weak_factory_;

  DISALLOW_COPY_AND_ASSIGN(EmbeddedTestServer);
};

}  // namespace test_servers
}  // namespace net

#endif  // NET_TEST_EMBEDDED_TEST_SERVER_EMBEDDED_TEST_SERVER_H_
