// Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Stub implementation of Samba net. Does not talk to server, but simply returns
// fixed responses to predefined input.

#include <string>
#include <vector>

#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/strings/string_split.h>
#include <base/strings/string_util.h>

#include "authpolicy/samba_helper.h"
#include "authpolicy/stub_common.h"

namespace authpolicy {
namespace {

// smbclient sub-commands.
constexpr char kLcdCommand[] = "lcd ";
constexpr char kCdCommand[] = "cd ";
constexpr char kGetCommand[] = "get ";

// Expected host and share in smbclient command. First part should match domain
// controller name in kStubLookup (see stub_net_main.cc).
constexpr char kHostAndShare[] = "//DCNAME.EXAMPLE.COM/SysVol";

// Error printed when a "remote" GPO fails to download.
constexpr char kGpoDownloadError[] =
    "NT_STATUS_ACCESS_DENIED opening remote file ";

// Error printed when a "remote" GPO file does not exist.
constexpr char kGpoDoesNotExistError[] =
    "NT_STATUS_OBJECT_NAME_NOT_FOUND opening remote file ";

// Error printed smbclient cannot connect to a host/share.
constexpr char kConnectionFailedError[] =
    "Connection to //<SERVER_NAME>/sysvol failed (Error "
    "NT_STATUS_UNSUCCESSFUL)";

struct DownloadItem {
  std::string remote_path_;
  std::string local_path_;
};

// Finds all 'cd <remote_dir>;lcd <local_dir>;get <filename>' triplets in an
// smbclient command and returns a list the concatenated local and remote file
// paths found.
std::vector<DownloadItem> GetDownloadItems(const std::string& command_line) {
  std::string remote_dir, local_dir;
  std::vector<DownloadItem> items;
  std::vector<std::string> subcommands = base::SplitString(
      command_line, ";", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
  for (const std::string& subcommand : subcommands) {
    if (StartsWithCaseSensitive(subcommand, kCdCommand)) {
      remote_dir = subcommand.substr(strlen(kCdCommand));
    } else if (StartsWithCaseSensitive(subcommand, kLcdCommand)) {
      local_dir = subcommand.substr(strlen(kLcdCommand));
    } else if (StartsWithCaseSensitive(subcommand, kGetCommand)) {
      const std::string filename = subcommand.substr(strlen(kGetCommand));
      DownloadItem item;
      item.remote_path_ = remote_dir + "\\" + filename;
      item.local_path_ = base::FilePath(local_dir).Append(filename).value();
      items.push_back(item);
    }
  }
  return items;
}

int HandleCommandLine(const std::string& command_line) {
  // Make sure the caller adds the debug level.
  CHECK(Contains(command_line, " -d "));

  if (!Contains(command_line, kHostAndShare)) {
    WriteOutput(kConnectionFailedError, "");
    return kExitCodeError;
  }

  // Stub GPO files are written to krb5.conf's directory because it's hard to
  // pass a full file path from a unit test to a stub binary. Note that
  // environment variables are NOT passed through ProcessExecutor.
  const base::FilePath gpo_dir =
      base::FilePath(GetKrb5ConfFilePath()).DirName();

  std::vector<DownloadItem> items = GetDownloadItems(command_line);
  for (const DownloadItem& item : items) {
    base::FilePath source_path;
    bool download_error = false;
    if (Contains(item.local_path_, kGpo1Guid))
      source_path = gpo_dir.Append(kGpo1Filename);
    else if (Contains(item.local_path_, kGpo2Guid))
      source_path = gpo_dir.Append(kGpo2Filename);
    else if (Contains(item.local_path_, kErrorGpoGuid))
      download_error = true;
    else
      NOTREACHED() << "UNHANDLED DOWNLOAD ITEM '" << item.local_path_ << "'";

    if (download_error) {
      // Print "download error" warning.
      WriteOutput(kGpoDownloadError + item.remote_path_, "");
    } else if (!base::PathExists(source_path)) {
      // Print "file does not exist" warning.
      WriteOutput(kGpoDoesNotExistError + item.remote_path_, "");
    } else {
      // "Download" the file.
      base::FilePath target_path(item.local_path_);
      CHECK(base::CopyFile(source_path, target_path));
    }
  }

  // The command should always end with 'exit;'. This makes sure smbclient
  // always exits with code 0.
  CHECK(base::EndsWith(command_line, "exit;", base::CompareCase::SENSITIVE));
  return kExitCodeOk;
}

}  // namespace
}  // namespace authpolicy

int main(int argc, char* argv[]) {
  const std::string command_line = authpolicy::GetCommandLine(argc, argv);
  return authpolicy::HandleCommandLine(command_line);
}
