/*
 * libjingle
 * Copyright 2004--2005, Google Inc.
 *
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice, 
 *     this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products 
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef _XMPPCLIENTSETTINGS_H_
#define _XMPPCLIENTSETTINGS_H_

#include "talk/p2p/base/port.h"
#include "talk/base/cryptstring.h"

namespace buzz {

class XmppUserSettings {
 public:
  XmppUserSettings()
    : use_tls_(false), 
      allow_plain_(false) {
  }

  void set_user(const std::string & user) { user_ = user; }
  void set_host(const std::string & host) { host_ = host; }
  void set_pass(const talk_base::CryptString & pass) { pass_ = pass; }
  void set_auth_cookie(const std::string & cookie) { auth_cookie_ = cookie; }
  void set_resource(const std::string & resource) { resource_ = resource; }
  void set_use_tls(bool use_tls) { use_tls_ = use_tls; }
  void set_allow_plain(bool f) { allow_plain_ = f; }
  void set_token_service(const std::string & token_service) {
    token_service_ = token_service;
  }

  const std::string & user() const { return user_; }
  const std::string & host() const { return host_; }
  const talk_base::CryptString & pass() const { return pass_; }
  const std::string & auth_cookie() const { return auth_cookie_; }
  const std::string & resource() const { return resource_; }
  bool use_tls() const { return use_tls_; }
  bool allow_plain() const { return allow_plain_; }
  const std::string & token_service() const { return token_service_; }

 private:
  std::string user_;
  std::string host_;
  talk_base::CryptString pass_;
  std::string auth_cookie_;
  std::string resource_;
  bool use_tls_;
  bool allow_plain_;
  std::string token_service_;
};

class XmppClientSettings : public XmppUserSettings {
 public:
  XmppClientSettings()
    : protocol_(cricket::PROTO_TCP),
      proxy_(talk_base::PROXY_NONE),
      proxy_port_(80),
      use_proxy_auth_(false) {
  }

  void set_server(const talk_base::SocketAddress & server) { 
      server_ = server; 
  }
  void set_protocol(cricket::ProtocolType protocol) { protocol_ = protocol; }
  void set_proxy(talk_base::ProxyType f) { proxy_ = f; }
  void set_proxy_host(const std::string & host) { proxy_host_ = host; }
  void set_proxy_port(int port) { proxy_port_ = port; };
  void set_use_proxy_auth(bool f) { use_proxy_auth_ = f; }
  void set_proxy_user(const std::string & user) { proxy_user_ = user; }
  void set_proxy_pass(const talk_base::CryptString & pass) { proxy_pass_ = pass; }

  const talk_base::SocketAddress & server() const { return server_; }
  cricket::ProtocolType protocol() const { return protocol_; }
  talk_base::ProxyType proxy() const { return proxy_; }
  const std::string & proxy_host() const { return proxy_host_; }
  int proxy_port() const { return proxy_port_; }
  bool use_proxy_auth() const { return use_proxy_auth_; }
  const std::string & proxy_user() const { return proxy_user_; }
  const talk_base::CryptString & proxy_pass() const { return proxy_pass_; }

 private:
  talk_base::SocketAddress server_;
  cricket::ProtocolType protocol_;
  talk_base::ProxyType proxy_;
  std::string proxy_host_;
  int proxy_port_;
  bool use_proxy_auth_;
  std::string proxy_user_;
  talk_base::CryptString proxy_pass_;
};

}

#endif
