// Copyright (C) 2004 Nico Schottelius <nico-linux-monotone@schottelius.org>
//
// This program is made available under the GNU GPL version 2.0 or
// greater. See the accompanying file COPYING for details.
//
// This program is distributed WITHOUT ANY WARRANTY; without even the
// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE.

#include "../base.hh"

#include <cstring>
#include <iostream>
#include <unistd.h>
#include <windows.h>

#include "../sanity.hh"

void
read_password(std::string const & prompt, char * buf, size_t bufsz)
{
  HANDLE mt_stdin;
  DWORD origmode, pwmode = 0;

  I(buf != NULL);

  mt_stdin = GetStdHandle(STD_INPUT_HANDLE);
  I(mt_stdin != INVALID_HANDLE_VALUE);
  I(mt_stdin != NULL); // NULL is non-interactive.  Can't get a passphrase if we're non-interactive
  if (GetConsoleMode(mt_stdin, &origmode) == 0)
  {
    /* This looks like we're not a real windows console.
       Possibly MSYS or Cygwin.  We'll do the best we can
       to make the password invisible in the absence of tcsetattr,
       namely emitting vt100 codes to change the foreground and
       background colour to the same thing.  If someone knows a
       better way, be my guest. */
    mt_stdin = NULL;
  }
  else
    pwmode = origmode & (~ENABLE_ECHO_INPUT);

  memset(buf, 0, bufsz);
  std::cout << prompt;
  std::cout.flush();

  if (mt_stdin != NULL)
  {
    I(SetConsoleMode(mt_stdin, pwmode) != 0);
    std::cin.getline(buf, bufsz, '\n');
    std::cout << std::endl;
    I(SetConsoleMode(mt_stdin, origmode) != 0);
  }
  else
  {
    std::cout << "\x1B\x37\x1B[30;40m";
    std::cout.flush();
    fgets(buf, bufsz, stdin); /* Sorry, but cin.getline just doesn't work under MinGW's rxvt */
    std::cout << "\x1B[0m\x1B\x38\n";
    std::cout.flush();

    /* ...and fgets gives us an LF we don't want */
    size_t bufend = strlen(buf)-1;
    if (buf[bufend]=='\x0A')
      buf[bufend] = '\0';
  }
}

// Local Variables:
// mode: C++
// fill-column: 76
// c-file-style: "gnu"
// indent-tabs-mode: nil
// End:
// vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s:
