// 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_ls.h"

#include <vector>

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

namespace {

bool LooksLikeUnixPermission(const string16& text) {
  if (text.length() != 3)
    return false;

  // Meaning of the flags:
  // r - file is readable
  // w - file is writable
  // x - file is executable
  // s or S - setuid/setgid bit set
  // t or T - "sticky" bit set
  return ((text[0] == 'r' || text[0] == '-') &&
          (text[1] == 'w' || text[1] == '-') &&
          (text[2] == 'x' || text[2] == 's' || text[2] == 'S' ||
           text[2] == 't' || text[2] == 'T' || text[2] == '-'));
}

bool LooksLikeUnixPermissionsListing(const string16& text) {
  if (text.length() < 7)
    return false;

  // Do not check the first character (entry type). There are many weird
  // servers that use special file types (for example Plan9 and append-only
  // files). Fortunately, the rest of the permission listing is more consistent.

  // Do not check the rest of the string. Some servers fail to properly
  // separate this column from the next column (number of links), resulting
  // in additional characters at the end. Also, sometimes there is a "+"
  // sign at the end indicating the file has ACLs set.

  // In fact, we don't even expect three "rwx" triplets of permission
  // listing, as some FTP servers like Hylafax only send two.
  return (LooksLikeUnixPermission(text.substr(1, 3)) &&
          LooksLikeUnixPermission(text.substr(4, 3)));
}

// Returns the column index of the end of the date listing and detected
// last modification time.
bool DetectColumnOffsetAndModificationTime(const std::vector<string16>& columns,
                                           const base::Time& current_time,
                                           size_t* offset,
                                           base::Time* modification_time) {
  // The column offset can be arbitrarily large if some fields
  // like owner or group name contain spaces. Try offsets from left to right
  // and use the first one that matches a date listing.
  //
  // Here is how a listing line should look like. A star ("*") indicates
  // a required field:
  //
  //  * 1. permission listing
  //    2. number of links (optional)
  //  * 3. owner name (may contain spaces)
  //    4. group name (optional, may contain spaces)
  //  * 5. size in bytes
  //  * 6. month
  //  * 7. day of month
  //  * 8. year or time <-- column_offset will be the index of this column
  //    9. file name (optional, may contain spaces)
  for (size_t i = 5U; i < columns.size(); i++) {
    if (net::FtpUtil::LsDateListingToTime(columns[i - 2],
                                          columns[i - 1],
                                          columns[i],
                                          current_time,
                                          modification_time)) {
      *offset = i;
      return true;
    }
  }

  // Some FTP listings have swapped the "month" and "day of month" columns
  // (for example Russian listings). We try to recognize them only after making
  // sure no column offset works above (this is a more strict way).
  for (size_t i = 5U; i < columns.size(); i++) {
    if (net::FtpUtil::LsDateListingToTime(columns[i - 1],
                                          columns[i - 2],
                                          columns[i],
                                          current_time,
                                          modification_time)) {
      *offset = i;
      return true;
    }
  }

  return false;
}

}  // namespace

namespace net {

bool ParseFtpDirectoryListingLs(
    const std::vector<string16>& lines,
    const base::Time& current_time,
    std::vector<FtpDirectoryListingEntry>* entries) {
  // True after we have received a "total n" listing header, where n is an
  // integer. Only one such header is allowed per listing.
  bool received_total_line = false;

  for (size_t i = 0; i < lines.size(); i++) {
    if (lines[i].empty())
      continue;

    std::vector<string16> columns;
    base::SplitString(CollapseWhitespace(lines[i], false), ' ', &columns);

    // Some FTP servers put a "total n" line at the beginning of the listing
    // (n is an integer). Allow such a line, but only once, and only if it's
    // the first non-empty line. Do not match the word exactly, because it may
    // be in different languages (at least English and German have been seen
    // in the field).
    if (columns.size() == 2 && !received_total_line) {
      received_total_line = true;

      int total_number;
      if (!base::StringToInt(columns[1], &total_number))
        return false;
      if (total_number < 0)
        return false;

      continue;
    }

    FtpDirectoryListingEntry entry;

    size_t column_offset;
    if (!DetectColumnOffsetAndModificationTime(columns,
                                               current_time,
                                               &column_offset,
                                               &entry.last_modified)) {
      // Some servers send a message in one of the first few lines.
      // All those messages have in common is the string ".:",
      // where "." means the current directory, and ":" separates it
      // from the rest of the message, which may be empty.
      if (lines[i].find(ASCIIToUTF16(".:")) != string16::npos)
        continue;

      return false;
    }

    if (!LooksLikeUnixPermissionsListing(columns[0]))
      return false;
    if (columns[0][0] == 'l') {
      entry.type = FtpDirectoryListingEntry::SYMLINK;
    } else if (columns[0][0] == 'd') {
      entry.type = FtpDirectoryListingEntry::DIRECTORY;
    } else {
      entry.type = FtpDirectoryListingEntry::FILE;
    }

    if (!base::StringToInt64(columns[column_offset - 3], &entry.size)) {
      // Some FTP servers do not separate owning group name from file size,
      // like "group1234". We still want to display the file name for that
      // entry, but can't really get the size (What if the group is named
      // "group1", and the size is in fact 234? We can't distinguish between
      // that and "group" with size 1234). Use a dummy value for the size.
      // TODO(phajdan.jr): Use a value that means "unknown" instead of 0 bytes.
      entry.size = 0;
    }
    if (entry.size < 0) {
      // Some FTP servers have bugs that cause them to display the file size
      // as negative. They're most likely big files like DVD ISO images.
      // We still want to display them, so just say the real file size
      // is unknown.
      entry.size = -1;
    }
    if (entry.type != FtpDirectoryListingEntry::FILE)
      entry.size = -1;

    if (column_offset == columns.size() - 1) {
      // If the end of the date listing is the last column, there is no file
      // name. Some FTP servers send listing entries with empty names.
      // It's not obvious how to display such an entry, so we ignore them.
      // We don't want to make the parsing fail at this point though.
      // Other entries can still be useful.
      continue;
    }

    entry.name = FtpUtil::GetStringPartAfterColumns(lines[i],
                                                    column_offset + 1);

    if (entry.type == FtpDirectoryListingEntry::SYMLINK) {
      string16::size_type pos = entry.name.rfind(ASCIIToUTF16(" -> "));

      // We don't require the " -> " to be present. Some FTP servers don't send
      // the symlink target, possibly for security reasons.
      if (pos != string16::npos)
        entry.name = entry.name.substr(0, pos);
    }

    entries->push_back(entry);
  }

  return true;
}

}  // namespace net
