// 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.

#include "net/ftp/ftp_directory_listing_parser_vms.h"

#include <vector>

#include "base/numerics/safe_math.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "net/ftp/ftp_directory_listing_parser.h"
#include "net/ftp/ftp_util.h"

namespace net {

namespace {

// Converts the filename component in listing to the filename we can display.
// Returns true on success.
bool ParseVmsFilename(const base::string16& raw_filename,
                      base::string16* parsed_filename,
                      FtpDirectoryListingEntry::Type* type) {
  // On VMS, the files and directories are versioned. The version number is
  // separated from the file name by a semicolon. Example: ANNOUNCE.TXT;2.
  std::vector<base::string16> listing_parts =
      base::SplitString(raw_filename, base::ASCIIToUTF16(";"),
                        base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
  if (listing_parts.size() != 2)
    return false;
  int version_number;
  if (!base::StringToInt(listing_parts[1], &version_number))
    return false;
  if (version_number < 0)
    return false;

  // Even directories have extensions in the listings. Don't display extensions
  // for directories; it's awkward for non-VMS users. Also, VMS is
  // case-insensitive, but generally uses uppercase characters. This may look
  // awkward, so we convert them to lower case.
  std::vector<base::string16> filename_parts =
      base::SplitString(listing_parts[0], base::ASCIIToUTF16("."),
                        base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
  if (filename_parts.size() != 2)
    return false;
  if (base::EqualsASCII(filename_parts[1], "DIR")) {
    *parsed_filename = base::ToLowerASCII(filename_parts[0]);
    *type = FtpDirectoryListingEntry::DIRECTORY;
  } else {
    *parsed_filename = base::ToLowerASCII(listing_parts[0]);
    *type = FtpDirectoryListingEntry::FILE;
  }
  return true;
}

// VMS's directory listing gives file size in blocks. The exact file size is
// unknown both because it is measured in blocks, but also because the block
// size is unknown (but assumed to be 512 bytes).
bool ApproximateFilesizeFromBlockCount(int64_t num_blocks, int64_t* out_size) {
  if (num_blocks < 0)
    return false;

  const int kBlockSize = 512;
  base::CheckedNumeric<int64_t> num_bytes = num_blocks;
  num_bytes *= kBlockSize;

  if (!num_bytes.IsValid())
    return false;  // Block count is too large.

  *out_size = num_bytes.ValueOrDie();
  return true;
}

bool ParseVmsFilesize(const base::string16& input, int64_t* size) {
  if (base::ContainsOnlyChars(input, base::ASCIIToUTF16("*"))) {
    // Response consisting of asterisks means unknown size.
    *size = -1;
    return true;
  }

  int64_t num_blocks;
  if (base::StringToInt64(input, &num_blocks))
    return ApproximateFilesizeFromBlockCount(num_blocks, size);

  std::vector<base::StringPiece16> parts =
      base::SplitStringPiece(input, base::ASCIIToUTF16("/"),
                             base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
  if (parts.size() != 2)
    return false;

  int64_t blocks_used, blocks_allocated;
  if (!base::StringToInt64(parts[0], &blocks_used))
    return false;
  if (!base::StringToInt64(parts[1], &blocks_allocated))
    return false;
  if (blocks_used > blocks_allocated)
    return false;
  if (blocks_used < 0 || blocks_allocated < 0)
    return false;

  return ApproximateFilesizeFromBlockCount(blocks_used, size);
}

bool LooksLikeVmsFileProtectionListingPart(const base::string16& input) {
  if (input.length() > 4)
    return false;

  // On VMS there are four different permission bits: Read, Write, Execute,
  // and Delete. They appear in that order in the permission listing.
  std::string pattern("RWED");
  base::string16 match(input);
  while (!match.empty() && !pattern.empty()) {
    if (match[0] == pattern[0])
      match = match.substr(1);
    pattern = pattern.substr(1);
  }
  return match.empty();
}

bool LooksLikeVmsFileProtectionListing(const base::string16& input) {
  if (input.length() < 2)
    return false;
  if (input.front() != '(' || input.back() != ')')
    return false;

  // We expect four parts of the file protection listing: for System, Owner,
  // Group, and World.
  std::vector<base::string16> parts = base::SplitString(
      base::StringPiece16(input).substr(1, input.length() - 2),
      base::ASCIIToUTF16(","), base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
  if (parts.size() != 4)
    return false;

  return LooksLikeVmsFileProtectionListingPart(parts[0]) &&
      LooksLikeVmsFileProtectionListingPart(parts[1]) &&
      LooksLikeVmsFileProtectionListingPart(parts[2]) &&
      LooksLikeVmsFileProtectionListingPart(parts[3]);
}

bool LooksLikeVmsUserIdentificationCode(const base::string16& input) {
  if (input.length() < 2)
    return false;
  return input.front() == '[' && input.back() == ']';
}

bool LooksLikeVMSError(const base::string16& text) {
  static const char* const kPermissionDeniedMessages[] = {
    "%RMS-E-FNF",  // File not found.
    "%RMS-E-PRV",  // Access denied.
    "%SYSTEM-F-NOPRIV",
    "privilege",
  };

  for (size_t i = 0; i < base::size(kPermissionDeniedMessages); i++) {
    if (text.find(base::ASCIIToUTF16(kPermissionDeniedMessages[i])) !=
        base::string16::npos)
      return true;
  }

  return false;
}

bool VmsDateListingToTime(const std::vector<base::string16>& columns,
                          base::Time* time) {
  DCHECK_EQ(4U, columns.size());

  base::Time::Exploded time_exploded = { 0 };

  // Date should be in format DD-MMM-YYYY.
  std::vector<base::StringPiece16> date_parts =
      base::SplitStringPiece(columns[2], base::ASCIIToUTF16("-"),
                             base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
  if (date_parts.size() != 3)
    return false;
  if (!base::StringToInt(date_parts[0], &time_exploded.day_of_month))
    return false;
  if (!FtpUtil::AbbreviatedMonthToNumber(date_parts[1].as_string(),
                                         &time_exploded.month))
    return false;
  if (!base::StringToInt(date_parts[2], &time_exploded.year))
    return false;

  // Time can be in format HH:MM, HH:MM:SS, or HH:MM:SS.mm. Try to recognize the
  // last type first. Do not parse the seconds, they will be ignored anyway.
  base::string16 time_column(columns[3]);
  if (time_column.length() == 11 && time_column[8] == '.')
    time_column = time_column.substr(0, 8);
  if (time_column.length() == 8 && time_column[5] == ':')
    time_column = time_column.substr(0, 5);
  if (time_column.length() != 5)
    return false;
  std::vector<base::StringPiece16> time_parts =
      base::SplitStringPiece(time_column, base::ASCIIToUTF16(":"),
                             base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
  if (time_parts.size() != 2)
    return false;
  if (!base::StringToInt(time_parts[0], &time_exploded.hour))
    return false;
  if (!base::StringToInt(time_parts[1], &time_exploded.minute))
    return false;

  // We don't know the time zone of the server, so just use UTC.
  return base::Time::FromUTCExploded(time_exploded, time);
}

}  // namespace

bool ParseFtpDirectoryListingVms(
    const std::vector<base::string16>& lines,
    std::vector<FtpDirectoryListingEntry>* entries) {
  // The first non-empty line is the listing header. It often
  // starts with "Directory ", but not always. We set a flag after
  // seing the header.
  bool seen_header = false;

  // Sometimes the listing doesn't end with a "Total" line, but
  // it's only okay when it contains some errors (it's needed
  // to distinguish it from "ls -l" format).
  bool seen_error = false;

  base::string16 total_of = base::ASCIIToUTF16("Total of ");
  base::char16 space[2] = { ' ', 0 };
  for (size_t i = 0; i < lines.size(); i++) {
    if (lines[i].empty())
      continue;

    if (base::StartsWith(lines[i], total_of, base::CompareCase::SENSITIVE)) {
      // After the "total" line, all following lines must be empty.
      for (size_t j = i + 1; j < lines.size(); j++)
        if (!lines[j].empty())
          return false;

      return true;
    }

    if (!seen_header) {
      seen_header = true;
      continue;
    }

    if (LooksLikeVMSError(lines[i])) {
      seen_error = true;
      continue;
    }

    std::vector<base::string16> columns = base::SplitString(
        base::CollapseWhitespace(lines[i], false), space,
        base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);

    if (columns.size() == 1) {
      // There can be no continuation if the current line is the last one.
      if (i == lines.size() - 1)
        return false;

      // Skip the next line.
      i++;

      // This refers to the continuation line.
      if (LooksLikeVMSError(lines[i])) {
        seen_error = true;
        continue;
      }

      // Join the current and next line and split them into columns.
      columns = base::SplitString(
          base::CollapseWhitespace(
              lines[i - 1] + space + lines[i], false),
          space, base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
    }

    if (columns.empty())
      return false;

    FtpDirectoryListingEntry entry;
    if (!ParseVmsFilename(columns[0], &entry.name, &entry.type))
      return false;

    // There are different variants of a VMS listing. Some display
    // the protection listing and user identification code, some do not.
    if (columns.size() == 6) {
      if (!LooksLikeVmsFileProtectionListing(columns[5]))
        return false;
      if (!LooksLikeVmsUserIdentificationCode(columns[4]))
        return false;

      // Drop the unneeded data, so that the following code can always expect
      // just four columns.
      columns.resize(4);
    }

    if (columns.size() != 4)
      return false;

    if (!ParseVmsFilesize(columns[1], &entry.size))
      return false;
    if (entry.type != FtpDirectoryListingEntry::FILE)
      entry.size = -1;
    if (!VmsDateListingToTime(columns, &entry.last_modified))
      return false;

    entries->push_back(entry);
  }

  // The only place where we return true is after receiving the "Total" line,
  // that should be present in every VMS listing. Alternatively, if the listing
  // contains error messages, it's OK not to have the "Total" line.
  return seen_error;
}

}  // namespace net
