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

#include "arc/container/obb-mounter/volume.h"

#include <endian.h>
#include <linux/msdos_fs.h>

#include <algorithm>
#include <string>
#include <utility>
#include <vector>

#include <base/callback.h>
#include <base/logging.h>

#include "arc/container/obb-mounter/util.h"

namespace fat {

namespace {

// Converts a msdos_dir_entry to a DirectoryEntry.
void MsdosDirEntryToDirectoryEntry(FatType fat_type,
                                   const msdos_dir_entry& in,
                                   Volume::DirectoryEntry* out) {
  out->is_directory = in.attr & ATTR_DIR;
  out->file_size = le32toh(in.size);
  out->start_cluster = le16toh(in.start);
  out->last_modification.date = le16toh(in.date);
  out->last_modification.time = le16toh(in.time);
  if (fat_type == FatType::FAT_32) {
    out->start_cluster += (le16toh(in.starthi) << 16);
  }
}

}  // namespace

base::Time Volume::Time::ToBaseTime() const {
  base::Time::Exploded exploded = {};
  exploded.year = 1980 + ((date >> 9) & 0x7f);
  exploded.month = (date >> 5) & 0x0f;
  exploded.day_of_month = date & 0x1f;
  exploded.hour = (time >> 11) & 0x1f;
  exploded.minute = (time >> 5) & 0x3f;
  exploded.second = (time & 0x1f) * 2;

  base::Time base_time;
  if (!base::Time::FromLocalExploded(exploded, &base_time)) {
    // In some cases, probably on DST switching timing, FromLocalExploded
    // may fail. In such a failure case, FromLocalExploded will return
    // base::Time(0) as its result, so this function still use it
    // with logging for the further investigation.
    LOG(ERROR) << "Time::FromLocalExploded failed with date: " << date
               << ", time: " << time;
  }
  return base_time;
}

Volume::FileReader::FileReader(Volume* volume,
                               int64_t start_cluster,
                               int64_t file_size)
    : volume_(volume),
      start_cluster_(start_cluster),
      file_size_(file_size),
      current_offset_(0),
      current_cluster_(start_cluster_) {}

Volume::FileReader::~FileReader() {}

int64_t Volume::FileReader::Read(char* buf, int64_t size, int64_t offset) {
  int64_t total = 0;
  const int64_t end_offset = std::min(offset + size, file_size_);
  while (offset + total < end_offset) {
    if (!Seek(offset + total)) {
      LOG(ERROR) << "Failed to seek.";
      return -1;
    }
    const int64_t cluster_size =
        volume_->bytes_per_sector_ * volume_->sectors_per_cluster_;
    const int64_t read_size =
        std::min(cluster_size - (current_offset_ % cluster_size),
                 end_offset - current_offset_);
    const int64_t position =
        volume_->GetSectorPosition(
            volume_->GetClusterStartSector(current_cluster_)) +
        current_offset_ % cluster_size;
    const int64_t read_bytes =
        volume_->image_file_.Read(position, buf + total, read_size);
    if (read_bytes == 0) {
      break;
    } else if (read_bytes < 0) {
      LOG(ERROR) << "Failed to read.";
      return -1;
    }
    total += read_bytes;
  }
  return total;
}

bool Volume::FileReader::Seek(int64_t offset) {
  if (offset < current_offset_) {
    // To move backward, we have to restart from the beginning.
    current_offset_ = 0;
    current_cluster_ = start_cluster_;
  }
  // Follow the cluster chain until we reach the target cluster.
  const int64_t cluster_size =
      volume_->bytes_per_sector_ * volume_->sectors_per_cluster_;
  const int64_t n_steps =
      offset / cluster_size - current_offset_ / cluster_size;
  for (int64_t i = 0; i < n_steps; ++i) {
    current_cluster_ = ReadFileAllocationTable(
        &volume_->image_file_, volume_->fat_type_,
        volume_->GetSectorPosition(volume_->fat_start_sector_),
        current_cluster_);
    if (current_cluster_ == kInvalidValue) {
      LOG(ERROR) << "Failed to track the cluster chain.";
      current_offset_ = 0;
      current_cluster_ = start_cluster_;
      return false;
    }
  }
  current_offset_ = offset;
  return true;
}

Volume::Volume() {}

Volume::~Volume() {}

bool Volume::Initialize(base::File image_file) {
  image_file_ = std::move(image_file);

  // The first sector is the boot sector.
  fat_boot_sector boot_sector = {};
  if (image_file_.Read(0, reinterpret_cast<char*>(&boot_sector),
                       sizeof(boot_sector)) != sizeof(boot_sector)) {
    LOG(ERROR) << "Failed to read the boot sector.";
    return false;
  }
  bytes_per_sector_ = GetUnalignedLE16(boot_sector.sector_size);
  if (bytes_per_sector_ <= 0 || bytes_per_sector_ % sizeof(msdos_dir_entry)) {
    LOG(ERROR) << "Invalid sector size " << bytes_per_sector_;
    return false;
  }
  sectors_per_cluster_ = boot_sector.sec_per_clus;
  if (sectors_per_cluster_ <= 0) {
    LOG(ERROR) << "Invalid cluster size " << sectors_per_cluster_;
    return false;
  }
  // A volume can contain multiple file allocation tables (FATs) for robustness.
  int n_fats = boot_sector.fats;
  if (n_fats <= 0) {
    LOG(ERROR) << "Invalid # of FATs " << n_fats;
    return false;
  }
  int64_t sectors_per_fat = le16toh(boot_sector.fat_length);
  bool is_fat32 = false;
  if (sectors_per_fat == 0) {  // This volume should be FAT32.
    is_fat32 = true;
    sectors_per_fat = le32toh(boot_sector.fat32.length);
  }
  if (sectors_per_fat <= 0) {
    LOG(ERROR) << "Invalid FAT size " << sectors_per_fat;
    return false;
  }
  int64_t total_sectors = GetUnalignedLE16(boot_sector.sectors);
  if (total_sectors == 0) {
    total_sectors = le32toh(boot_sector.total_sect);
  }
  // File allocation tables (FATs) after the reserved sectors (including the
  // boot sector).
  fat_start_sector_ = le16toh(boot_sector.reserved);
  if (fat_start_sector_ < 1) {
    LOG(ERROR) << "Invalid FAT start sector " << fat_start_sector_;
    return false;
  }
  if (is_fat32) {
    // FAT32 explicitly specifies the position of the root dir.
    data_start_sector_ = fat_start_sector_ + n_fats * sectors_per_fat;
    root_dir_start_sector_ =
        GetClusterStartSector(le32toh(boot_sector.fat32.root_cluster));
    if (root_dir_start_sector_ < data_start_sector_ ||
        total_sectors <= root_dir_start_sector_) {
      LOG(ERROR) << "Invalid root dir start sector " << root_dir_start_sector_;
      return false;
    }
  } else {
    // FAT12/16 puts the root dir between the FATs and the data region.
    root_dir_start_sector_ = fat_start_sector_ + n_fats * sectors_per_fat;
    int n_root_dir_entries = GetUnalignedLE16(boot_sector.dir_entries);
    int size = sizeof(msdos_dir_entry) * n_root_dir_entries;
    if (size % bytes_per_sector_) {
      LOG(ERROR) << "Invalid # of root directory entries.";
      return false;
    }
    data_start_sector_ = root_dir_start_sector_ + size / bytes_per_sector_;
  }
  // Data region after the FATs and the FAT12/16 root dir.
  int64_t data_sectors = total_sectors - data_start_sector_;
  if (data_sectors < 0) {
    LOG(ERROR) << "Invalid # of data sectors " << data_sectors;
    return false;
  }
  if (is_fat32) {
    fat_type_ = FatType::FAT_32;
  } else {
    // Use the # of cluster to determine the FAT type.
    int64_t n_clusters = data_sectors / sectors_per_cluster_;
    if (n_clusters > MAX_FAT12) {
      fat_type_ = FatType::FAT_16;
    } else {
      fat_type_ = FatType::FAT_12;
    }
  }
  return true;
}

bool Volume::ReadDirectory(int64_t start_sector,
                           const ReadDirectoryCallback& callback) {
  std::vector<char> dir_entry_buf(bytes_per_sector_);
  std::vector<base::char16> long_name_buf;
  for (int64_t pos = 0, sector = start_sector;
       pos < FAT_MAX_DIR_SIZE && sector != kInvalidValue;
       pos += bytes_per_sector_, sector = GetNextSector(sector)) {
    // Read the sector.
    if (image_file_.Read(GetSectorPosition(sector), dir_entry_buf.data(),
                         dir_entry_buf.size()) !=
        static_cast<int>(dir_entry_buf.size())) {
      LOG(ERROR) << "Failed to read sector " << sector;
      return false;
    }
    // Visit each directory entry.
    for (size_t offset = 0; offset < dir_entry_buf.size();
         offset += sizeof(msdos_dir_entry)) {
      const auto& dir_entry = *reinterpret_cast<const msdos_dir_entry*>(
          dir_entry_buf.data() + offset);
      switch (dir_entry.name[0]) {
        case 0:  // Terminate.
          return true;
        case DELETED_FLAG:  // This entry is unused.
          continue;
      }
      if (dir_entry.attr == ATTR_EXT) {
        // This is a long file name slot for the coming directory entry.
        AppendLongFileNameCharactersReversed(
            reinterpret_cast<const msdos_dir_slot&>(dir_entry), &long_name_buf);
        continue;
      }
      // This is a directory entry.
      // long_name_buf holds characters in the reversed order.
      std::reverse(long_name_buf.begin(), long_name_buf.end());
      // Find 0 and truncate at it if found.
      auto it = std::find(long_name_buf.begin(), long_name_buf.end(), 0);
      if (it != long_name_buf.end()) {
        long_name_buf.resize(it - long_name_buf.begin());
      }
      if (long_name_buf.empty()) {
        // Ignoring entries without long names.
        // TODO(hashimoto): Use short name if long name is not available?

        // A non-root directory contains "." and ".." without long names,
        // but we ignore them intentionally.
        static const char kDot[MSDOS_NAME + 1] = ".          ";
        static const char kDotDot[MSDOS_NAME + 1] = "..         ";
        const bool expected = memcmp(kDot, dir_entry.name, MSDOS_NAME) == 0 ||
                              memcmp(kDotDot, dir_entry.name, MSDOS_NAME) == 0;
        // Log only when ignoring unexpected entries.
        LOG_IF(WARNING, !expected)
            << "Ignoring: "
            << std::string(dir_entry.name, dir_entry.name + MSDOS_NAME);
        continue;
      }
      DirectoryEntry entry;
      MsdosDirEntryToDirectoryEntry(fat_type_, dir_entry, &entry);
      if (!callback.Run(
              base::StringPiece16(long_name_buf.data(), long_name_buf.size()),
              entry)) {
        return true;
      }
    }
  }
  return true;
}

int64_t Volume::GetNextSector(int64_t sector) {
  if (sector >= data_start_sector_) {
    // We're in the data region. Follow the cluster chain.
    const int64_t cluster = GetCluster(sector);
    const int64_t cluster_end_sector =
        GetClusterStartSector(cluster) + sectors_per_cluster_;
    if (sector + 1 >= cluster_end_sector) {
      // Move to the next cluster.
      const int64_t next_cluster = ReadFileAllocationTable(
          &image_file_, fat_type_, GetSectorPosition(fat_start_sector_),
          cluster);
      if (next_cluster == kInvalidValue) {
        return kInvalidValue;
      }
      return GetClusterStartSector(next_cluster);
    }
    // Move ahead in the current cluster.
    return sector + 1;
  }
  if (sector >= root_dir_start_sector_) {
    // We're in the FAT16 root directory region.
    if (sector + 1 >= data_start_sector_) {  // Reached the end.
      return kInvalidValue;
    }
    return sector + 1;
  }
  // Invalid argument.
  return kInvalidValue;
}

}  // namespace fat
