// 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_HTTP_RESPONSE_H_
#define NET_TEST_EMBEDDED_TEST_SERVER_HTTP_RESPONSE_H_

#include <string>

#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/strings/string_split.h"
#include "net/http/http_status_code.h"

namespace net {
namespace test_server {

// Callback called when the response is done being sent.
using SendCompleteCallback = base::Callback<void(void)>;

// Callback called when the response is ready to be sent that takes the
// |response| that is being sent along with the callback |write_done| that is
// called when the response has been fully written.
using SendBytesCallback =
    base::Callback<void(const std::string& response,
                        const SendCompleteCallback& write_done)>;

// Interface for HTTP response implementations.
class HttpResponse{
 public:
  virtual ~HttpResponse();

  // |send| will send the specified data to the network socket, and invoke
  // |write_done| when complete. When the entire response has been sent,
  // |done| must be called.
  virtual void SendResponse(const SendBytesCallback& send,
                            const SendCompleteCallback& done) = 0;
};

// This class is used to handle basic HTTP responses with commonly used
// response headers such as "Content-Type". Sends the response immediately.
class BasicHttpResponse : public HttpResponse {
 public:
  BasicHttpResponse();
  ~BasicHttpResponse() override;

  // The response code.
  HttpStatusCode code() const { return code_; }
  void set_code(HttpStatusCode code) { code_ = code; }

  // The content of the response.
  const std::string& content() const { return content_; }
  void set_content(const std::string& content) { content_ = content; }

  // The content type.
  const std::string& content_type() const { return content_type_; }
  void set_content_type(const std::string& content_type) {
    content_type_ = content_type;
  }

  // Adds a custom header.
  void AddCustomHeader(const std::string& key, const std::string& value) {
    custom_headers_.push_back(std::make_pair(key, value));
  }

  // Generates and returns a http response string.
  std::string ToResponseString() const;

  void SendResponse(const SendBytesCallback& send,
                    const SendCompleteCallback& done) override;

 private:
  HttpStatusCode code_;
  std::string content_;
  std::string content_type_;
  base::StringPairs custom_headers_;

  DISALLOW_COPY_AND_ASSIGN(BasicHttpResponse);
};

class RawHttpResponse : public HttpResponse {
 public:
  RawHttpResponse(const std::string& headers, const std::string& contents);
  ~RawHttpResponse() override;

  void SendResponse(const SendBytesCallback& send,
                    const SendCompleteCallback& done) override;

  void AddHeader(const std::string& key_value_pair);

 private:
  std::string headers_;
  const std::string contents_;

  DISALLOW_COPY_AND_ASSIGN(RawHttpResponse);
};

}  // namespace test_server
}  // namespace net

#endif  // NET_TEST_EMBEDDED_TEST_SERVER_HTTP_RESPONSE_H_
