#define _CRT_SECURE_NO_DEPRECATE 1

#include <time.h>

#include <iomanip>
#include <iostream>
#include <string>

#if HAVE_CONFIG_H
#include "config.h"
#endif  // HAVE_CONFIG_H

#if HAVE_OPENSSL_SSL_H
#define USE_SSL_TUNNEL
#endif

#include "talk/base/basicdefs.h"
#include "talk/base/common.h"
#include "talk/base/helpers.h"
#include "talk/base/logging.h"
#include "talk/base/ssladapter.h"
#include "talk/base/stringutils.h"
#include "talk/base/thread.h"
#include "talk/examples/login/autoportallocator.h"
#include "talk/examples/login/xmpppump.h"
#include "talk/examples/login/xmppsocket.h"
#include "talk/p2p/base/sessionmanager.h"
#include "talk/p2p/client/sessionmanagertask.h"
#include "talk/xmpp/xmppengine.h"
#ifdef USE_SSL_TUNNEL
#include "talk/session/tunnel/securetunnelsessionclient.h"
#endif
#include "talk/session/tunnel/tunnelsessionclient.h"
#include "talk/xmpp/xmppclient.h"
#include "talk/xmpp/xmppclientsettings.h"

#ifndef MAX_PATH
#define MAX_PATH 256
#endif

#if defined(_MSC_VER) && (_MSC_VER < 1400)
// The following are necessary to properly link when compiling STL without
// /EHsc, otherwise known as C++ exceptions.
void __cdecl std::_Throw(const std::exception &) {}
std::_Prhand std::_Raise_handler = 0;
#endif

enum {
  MSG_LOGIN_COMPLETE = 1,
  MSG_LOGIN_FAILED,
  MSG_DONE,
};

buzz::Jid gUserJid;
talk_base::InsecureCryptStringImpl gUserPass;
std::string gXmppHost = "talk.google.com";
int gXmppPort = 5222;
buzz::TlsOptions gXmppUseTls = buzz::TLS_REQUIRED;

class DebugLog : public sigslot::has_slots<> {
public:
  DebugLog() :
    debug_input_buf_(NULL), debug_input_len_(0), debug_input_alloc_(0),
    debug_output_buf_(NULL), debug_output_len_(0), debug_output_alloc_(0),
    censor_password_(false)
      {}
  char * debug_input_buf_;
  int debug_input_len_;
  int debug_input_alloc_;
  char * debug_output_buf_;
  int debug_output_len_;
  int debug_output_alloc_;
  bool censor_password_;

  void Input(const char * data, int len) {
    if (debug_input_len_ + len > debug_input_alloc_) {
      char * old_buf = debug_input_buf_;
      debug_input_alloc_ = 4096;
      while (debug_input_alloc_ < debug_input_len_ + len) {
        debug_input_alloc_ *= 2;
      }
      debug_input_buf_ = new char[debug_input_alloc_];
      memcpy(debug_input_buf_, old_buf, debug_input_len_);
      delete[] old_buf;
    }
    memcpy(debug_input_buf_ + debug_input_len_, data, len);
    debug_input_len_ += len;
    DebugPrint(debug_input_buf_, &debug_input_len_, false);
  }

  void Output(const char * data, int len) {
    if (debug_output_len_ + len > debug_output_alloc_) {
      char * old_buf = debug_output_buf_;
      debug_output_alloc_ = 4096;
      while (debug_output_alloc_ < debug_output_len_ + len) {
        debug_output_alloc_ *= 2;
      }
      debug_output_buf_ = new char[debug_output_alloc_];
      memcpy(debug_output_buf_, old_buf, debug_output_len_);
      delete[] old_buf;
    }
    memcpy(debug_output_buf_ + debug_output_len_, data, len);
    debug_output_len_ += len;
    DebugPrint(debug_output_buf_, &debug_output_len_, true);
  }

  static bool
  IsAuthTag(const char * str, size_t len) {
    if (str[0] == '<' && str[1] == 'a' &&
                         str[2] == 'u' &&
                         str[3] == 't' &&
                         str[4] == 'h' &&
                         str[5] <= ' ') {
      std::string tag(str, len);

      if (tag.find("mechanism") != std::string::npos)
        return true;

    }
    return false;
  }

  void
  DebugPrint(char * buf, int * plen, bool output) {
    int len = *plen;
    if (len > 0) {
      time_t tim = time(NULL);
      struct tm * now = localtime(&tim);
      char *time_string = asctime(now);
      if (time_string) {
        size_t time_len = strlen(time_string);
        if (time_len > 0) {
          time_string[time_len-1] = 0;    // trim off terminating \n
        }
      }
      LOG(INFO) << (output ? "SEND >>>>>>>>>>>>>>>>>>>>>>>>>" : "RECV <<<<<<<<<<<<<<<<<<<<<<<<<")
        << " : " << time_string;

      bool indent;
      int start = 0, nest = 3;
      for (int i = 0; i < len; i += 1) {
        if (buf[i] == '>') {
          if ((i > 0) && (buf[i-1] == '/')) {
            indent = false;
          } else if ((start + 1 < len) && (buf[start + 1] == '/')) {
            indent = false;
            nest -= 2;
          } else {
            indent = true;
          }

          // Output a tag
          LOG(INFO) << std::setw(nest) << " " << std::string(buf + start, i + 1 - start);

          if (indent)
            nest += 2;

          // Note if it's a PLAIN auth tag
          if (IsAuthTag(buf + start, i + 1 - start)) {
            censor_password_ = true;
          }

          // incr
          start = i + 1;
        }

        if (buf[i] == '<' && start < i) {
          if (censor_password_) {
            LOG(INFO) << std::setw(nest) << " " << "## TEXT REMOVED ##";
            censor_password_ = false;
          }
          else {
            LOG(INFO) << std::setw(nest) << " " << std::string(buf + start, i - start);
          }
          start = i;
        }
      }
      len = len - start;
      memcpy(buf, buf + start, len);
      *plen = len;
    }
  }

};

static DebugLog debug_log_;

// Prints out a usage message then exits.
void Usage() {
  std::cerr << "Usage:" << std::endl;
  std::cerr << "  pcp [options] <my_jid>                             (server mode)" << std::endl;
  std::cerr << "  pcp [options] <my_jid> <src_file> <dst_full_jid>:<dst_file> (client sending)" << std::endl;
  std::cerr << "  pcp [options] <my_jid> <src_full_jid>:<src_file> <dst_file> (client rcv'ing)" << std::endl;
  std::cerr << "           --verbose" << std::endl;
  std::cerr << "           --xmpp-host=<host>" << std::endl;
  std::cerr << "           --xmpp-port=<port>" << std::endl;
  std::cerr << "           --xmpp-use-tls=(true|false)" << std::endl;
  exit(1);
}

// Prints out an error message, a usage message, then exits.
void Error(const std::string& msg) {
  std::cerr << "error: " << msg << std::endl;
  std::cerr << std::endl;
  Usage();
}

void FatalError(const std::string& msg) {
  std::cerr << "error: " << msg << std::endl;
  std::cerr << std::endl;
  exit(1);
}

// Determines whether the given string is an option.  If so, the name and
// value are appended to the given strings.
bool ParseArg(const char* arg, std::string* name, std::string* value) {
  if (strncmp(arg, "--", 2) != 0)
    return false;

  const char* eq = strchr(arg + 2, '=');
  if (eq) {
    if (name)
      name->append(arg + 2, eq);
    if (value)
      value->append(eq + 1, arg + strlen(arg));
  } else {
    if (name)
      name->append(arg + 2, arg + strlen(arg));
    if (value)
      value->clear();
  }

  return true;
}

int ParseIntArg(const std::string& name, const std::string& value) {
  char* end;
  long val = strtol(value.c_str(), &end, 10);
  if (*end != '\0')
    Error(std::string("value of option ") + name + " must be an integer");
  return static_cast<int>(val);
}

#ifdef WIN32
#pragma warning(push)
// disable "unreachable code" warning b/c it varies between dbg and opt
#pragma warning(disable: 4702)
#endif
bool ParseBoolArg(const std::string& name, const std::string& value) {
  if (value == "true")
    return true;
  else if (value == "false")
    return false;
  else {
    Error(std::string("value of option ") + name + " must be true or false");
    return false;
  }
}
#ifdef WIN32
#pragma warning(pop)
#endif

void ParseFileArg(const char* arg, buzz::Jid* jid, std::string* file) {
  const char* sep = strchr(arg, ':');
  if (!sep) {
    *file = arg;
  } else {
    buzz::Jid jid_arg(std::string(arg, sep-arg));
    if (jid_arg.IsBare())
      Error("A full JID is required for the source or destination arguments.");
    *jid = jid_arg;
    *file = std::string(sep+1);
  }
}


void SetConsoleEcho(bool on) {
#ifdef WIN32
  HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE);
  if ((hIn == INVALID_HANDLE_VALUE) || (hIn == NULL))
    return;

  DWORD mode;
  if (!GetConsoleMode(hIn, &mode))
    return;

  if (on) {
    mode = mode | ENABLE_ECHO_INPUT;
  } else {
    mode = mode & ~ENABLE_ECHO_INPUT;
  }

  SetConsoleMode(hIn, mode);
#else
  int re;
  if (on)
    re = system("stty echo");
  else
    re = system("stty -echo");
  if (-1 == re)
    return;
#endif
}

// Fills in a settings object with the values from the arguments.
buzz::XmppClientSettings LoginSettings() {
  buzz::XmppClientSettings xcs;
  xcs.set_user(gUserJid.node());
  xcs.set_host(gUserJid.domain());
  xcs.set_resource("pcp");
  xcs.set_pass(talk_base::CryptString(gUserPass));
  talk_base::SocketAddress server(gXmppHost, gXmppPort);
  xcs.set_server(server);
  xcs.set_use_tls(gXmppUseTls);
  return xcs;
}

// Runs the current thread until a message with the given ID is seen.
uint32 Loop(const std::vector<uint32>& ids) {
  talk_base::Message msg;
  while (talk_base::Thread::Current()->Get(&msg)) {
    if (msg.phandler == NULL) {
      if (std::find(ids.begin(), ids.end(), msg.message_id) != ids.end())
        return msg.message_id;
      std::cout << "orphaned message: " << msg.message_id;
      continue;
    }
    talk_base::Thread::Current()->Dispatch(&msg);
  }
  return 0;
}

#ifdef WIN32
#pragma warning(disable:4355)
#endif

class CustomXmppPump : public XmppPumpNotify, public XmppPump {
public:
  CustomXmppPump() : XmppPump(this), server_(false) { }

  void Serve(cricket::TunnelSessionClient* client) {
    client->SignalIncomingTunnel.connect(this,
      &CustomXmppPump::OnIncomingTunnel);
    server_ = true;
  }

  void OnStateChange(buzz::XmppEngine::State state) {
    switch (state) {
    case buzz::XmppEngine::STATE_START:
      std::cout << "connecting..." << std::endl;
      break;
    case buzz::XmppEngine::STATE_OPENING:
      std::cout << "logging in..." << std::endl;
      break;
    case buzz::XmppEngine::STATE_OPEN:
      std::cout << "logged in..." << std::endl;
      talk_base::Thread::Current()->Post(NULL, MSG_LOGIN_COMPLETE);
      break;
    case buzz::XmppEngine::STATE_CLOSED:
      std::cout << "logged out..." << std::endl;
      talk_base::Thread::Current()->Post(NULL, MSG_LOGIN_FAILED);
      break;
    }
  }

  void OnIncomingTunnel(cricket::TunnelSessionClient* client, buzz::Jid jid,
    std::string description, cricket::Session* session) {
    std::cout << "IncomingTunnel from " << jid.Str()
      << ": " << description << std::endl;
    if (!server_ || (file_.get() != NULL)) {
      client->DeclineTunnel(session);
      return;
    }
    std::string filename;
    bool send;
    if (strncmp(description.c_str(), "send:", 5) == 0) {
      send = true;
    } else if (strncmp(description.c_str(), "recv:", 5) == 0) {
      send = false;
    } else {
      client->DeclineTunnel(session);
      return;
    }
    filename = description.substr(5);
    talk_base::StreamInterface* stream = client->AcceptTunnel(session);
    if (!ProcessStream(stream, filename, send))
      talk_base::Thread::Current()->Post(NULL, MSG_DONE);

    // TODO: There is a potential memory leak, however, since the PCP
    // app doesn't work right now, I can't verify the fix actually works, so
    // comment out the following line until we fix the PCP app.

    // delete stream;
  }

  bool ProcessStream(talk_base::StreamInterface* stream,
                     const std::string& filename, bool send) {
    ASSERT(file_.get() == NULL);
    sending_ = send;
    file_.reset(new talk_base::FileStream);
    buffer_len_ = 0;
    int err;
    if (!file_->Open(filename.c_str(), sending_ ? "rb" : "wb", &err)) {
      std::cerr << "Error opening <" << filename << ">: "
                << std::strerror(err) << std::endl;
      return false;
    }
    stream->SignalEvent.connect(this, &CustomXmppPump::OnStreamEvent);
    if (stream->GetState() == talk_base::SS_CLOSED) {
      std::cerr << "Failed to establish P2P tunnel" << std::endl;
      return false;
    }
    if (stream->GetState() == talk_base::SS_OPEN) {
      OnStreamEvent(stream,
        talk_base::SE_OPEN | talk_base::SE_READ | talk_base::SE_WRITE, 0);
    }
    return true;
  }

  void OnStreamEvent(talk_base::StreamInterface* stream, int events,
                     int error) {
    if (events & talk_base::SE_CLOSE) {
      if (error == 0) {
        std::cout << "Tunnel closed normally" << std::endl;
      } else {
        std::cout << "Tunnel closed with error: " << error << std::endl;
      }
      Cleanup(stream);
      return;
    }
    if (events & talk_base::SE_OPEN) {
      std::cout << "Tunnel connected" << std::endl;
    }
    talk_base::StreamResult result;
    size_t count;
    if (sending_ && (events & talk_base::SE_WRITE)) {
      LOG(LS_VERBOSE) << "Tunnel SE_WRITE";
      while (true) {
        size_t write_pos = 0;
        while (write_pos < buffer_len_) {
          result = stream->Write(buffer_ + write_pos, buffer_len_ - write_pos,
                                &count, &error);
          if (result == talk_base::SR_SUCCESS) {
            write_pos += count;
            continue;
          }
          if (result == talk_base::SR_BLOCK) {
            buffer_len_ -= write_pos;
            memmove(buffer_, buffer_ + write_pos, buffer_len_);
            LOG(LS_VERBOSE) << "Tunnel write block";
            return;
          }
          if (result == talk_base::SR_EOS) {
            std::cout << "Tunnel closed unexpectedly on write" << std::endl;
          } else {
            std::cout << "Tunnel write error: " << error << std::endl;
          }
          Cleanup(stream);
          return;
        }
        buffer_len_ = 0;
        while (buffer_len_ < sizeof(buffer_)) {
          result = file_->Read(buffer_ + buffer_len_,
                              sizeof(buffer_) - buffer_len_,
                              &count, &error);
          if (result == talk_base::SR_SUCCESS) {
            buffer_len_ += count;
            continue;
          }
          if (result == talk_base::SR_EOS) {
            if (buffer_len_ > 0)
              break;
            std::cout << "End of file" << std::endl;
            // A hack until we have friendly shutdown
            Cleanup(stream, true);
            return;
          } else if (result == talk_base::SR_BLOCK) {
            std::cout << "File blocked unexpectedly on read" << std::endl;
          } else {
            std::cout << "File read error: " << error << std::endl;
          }
          Cleanup(stream);
          return;
        }
      }
    }
    if (!sending_ && (events & talk_base::SE_READ)) {
      LOG(LS_VERBOSE) << "Tunnel SE_READ";
      while (true) {
        buffer_len_ = 0;
        while (buffer_len_ < sizeof(buffer_)) {
          result = stream->Read(buffer_ + buffer_len_,
                                sizeof(buffer_) - buffer_len_,
                                &count, &error);
          if (result == talk_base::SR_SUCCESS) {
            buffer_len_ += count;
            continue;
          }
          if (result == talk_base::SR_BLOCK) {
            if (buffer_len_ > 0)
              break;
            LOG(LS_VERBOSE) << "Tunnel read block";
            return;
          }
          if (result == talk_base::SR_EOS) {
            std::cout << "Tunnel closed unexpectedly on read" << std::endl;
          } else {
            std::cout << "Tunnel read error: " << error << std::endl;
          }
          Cleanup(stream);
          return;
        }
        size_t write_pos = 0;
        while (write_pos < buffer_len_) {
          result = file_->Write(buffer_ + write_pos, buffer_len_ - write_pos,
                                &count, &error);
          if (result == talk_base::SR_SUCCESS) {
            write_pos += count;
            continue;
          }
          if (result == talk_base::SR_EOS) {
            std::cout << "File closed unexpectedly on write" << std::endl;
          } else if (result == talk_base::SR_BLOCK) {
            std::cout << "File blocked unexpectedly on write" << std::endl;
          } else {
            std::cout << "File write error: " << error << std::endl;
          }
          Cleanup(stream);
          return;
        }
      }
    }
  }

  void Cleanup(talk_base::StreamInterface* stream, bool delay = false) {
    LOG(LS_VERBOSE) << "Closing";
    stream->Close();
    file_.reset();
    if (!server_) {
      if (delay)
        talk_base::Thread::Current()->PostDelayed(2000, NULL, MSG_DONE);
      else
        talk_base::Thread::Current()->Post(NULL, MSG_DONE);
    }
  }

private:
  bool server_, sending_;
  talk_base::scoped_ptr<talk_base::FileStream> file_;
  char buffer_[1024 * 64];
  size_t buffer_len_;
};

int main(int argc, char **argv) {
  talk_base::LogMessage::LogThreads();
  talk_base::LogMessage::LogTimestamps();

  // TODO: Default the username to the current users's name.

  // Parse the arguments.

  int index = 1;
  while (index < argc) {
    std::string name, value;
    if (!ParseArg(argv[index], &name, &value))
      break;

    if (name == "help") {
      Usage();
    } else if (name == "verbose") {
      talk_base::LogMessage::LogToDebug(talk_base::LS_VERBOSE);
    } else if (name == "xmpp-host") {
      gXmppHost = value;
    } else if (name == "xmpp-port") {
      gXmppPort = ParseIntArg(name, value);
    } else if (name == "xmpp-use-tls") {
      gXmppUseTls = ParseBoolArg(name, value)?
          buzz::TLS_REQUIRED : buzz::TLS_DISABLED;
    } else {
      Error(std::string("unknown option: ") + name);
    }

    index += 1;
  }

  if (index >= argc)
    Error("bad arguments");
  gUserJid = buzz::Jid(argv[index++]);
  if (!gUserJid.IsValid())
    Error("bad arguments");

  char path[MAX_PATH];
#if WIN32
  GetCurrentDirectoryA(MAX_PATH, path);
#else
  if (NULL == getcwd(path, MAX_PATH))
    Error("Unable to get current path");
#endif

  std::cout << "Directory: " << std::string(path) << std::endl;

  buzz::Jid gSrcJid;
  buzz::Jid gDstJid;
  std::string gSrcFile;
  std::string gDstFile;

  bool as_server = true;
  if (index + 2 == argc) {
    ParseFileArg(argv[index], &gSrcJid, &gSrcFile);
    ParseFileArg(argv[index+1], &gDstJid, &gDstFile);
    if(gSrcJid.Str().empty() == gDstJid.Str().empty())
      Error("Exactly one of source JID or destination JID must be empty.");
    as_server = false;
  } else if (index != argc) {
    Error("bad arguments");
  }

  std::cout << "Password: ";
  SetConsoleEcho(false);
  std::cin >> gUserPass.password();
  SetConsoleEcho(true);
  std::cout << std::endl;

  talk_base::InitializeSSL();
  // Log in.
  CustomXmppPump pump;
  pump.client()->SignalLogInput.connect(&debug_log_, &DebugLog::Input);
  pump.client()->SignalLogOutput.connect(&debug_log_, &DebugLog::Output);
  pump.DoLogin(LoginSettings(), new XmppSocket(gXmppUseTls), 0);
    //new XmppAuth());

  // Wait until login succeeds.
  std::vector<uint32> ids;
  ids.push_back(MSG_LOGIN_COMPLETE);
  ids.push_back(MSG_LOGIN_FAILED);
  if (MSG_LOGIN_FAILED == Loop(ids))
    FatalError("Failed to connect");

  {
    talk_base::scoped_ptr<buzz::XmlElement> presence(
      new buzz::XmlElement(buzz::QN_PRESENCE));
    presence->AddElement(new buzz::XmlElement(buzz::QN_PRIORITY));
    presence->AddText("-1", 1);
    pump.SendStanza(presence.get());
  }

  std::string user_jid_str = pump.client()->jid().Str();
  std::cout << "Logged in as " << user_jid_str << std::endl;

  // Prepare the random number generator.
  talk_base::InitRandom(user_jid_str.c_str(), user_jid_str.size());

  // Create the P2P session manager.
  talk_base::BasicNetworkManager network_manager;
  AutoPortAllocator allocator(&network_manager, "pcp_agent");
  allocator.SetXmppClient(pump.client());
  cricket::SessionManager session_manager(&allocator);
#ifdef USE_SSL_TUNNEL
  cricket::SecureTunnelSessionClient session_client(pump.client()->jid(),
                                                    &session_manager);
  if (!session_client.GenerateIdentity())
    FatalError("Failed to generate SSL identity");
#else  // !USE_SSL_TUNNEL
  cricket::TunnelSessionClient session_client(pump.client()->jid(),
                                              &session_manager);
#endif  // USE_SSL_TUNNEL
  cricket::SessionManagerTask *receiver =
      new cricket::SessionManagerTask(pump.client(), &session_manager);
  receiver->EnableOutgoingMessages();
  receiver->Start();

  bool success = true;

  // Establish the appropriate connection.
  if (as_server) {
    pump.Serve(&session_client);
  } else {
    talk_base::StreamInterface* stream = NULL;
    std::string filename;
    bool sending;
    if (gSrcJid.Str().empty()) {
      std::string message("recv:");
      message.append(gDstFile);
      stream = session_client.CreateTunnel(gDstJid, message);
      filename = gSrcFile;
      sending = true;
    } else {
      std::string message("send:");
      message.append(gSrcFile);
      stream = session_client.CreateTunnel(gSrcJid, message);
      filename = gDstFile;
      sending = false;
    }
    success = pump.ProcessStream(stream, filename, sending);
  }

  if (success) {
    // Wait until the copy is done.
    ids.clear();
    ids.push_back(MSG_DONE);
    ids.push_back(MSG_LOGIN_FAILED);
    Loop(ids);
  }

  // Log out.
  pump.DoDisconnect();

  return 0;
}
