// 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<BasicHttpResponse> http_response(new BasicHttpResponse());
//   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_
