// Copyright 2018 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 <stdlib.h>

#include <memory>
#include <utility>

#include <base/environment.h>
#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 "vm_tools/garcon/desktop_file.h"
#include "vm_tools/garcon/ini_parse_util.h"

namespace {
// Ridiculously large size for a desktop file.
constexpr size_t kMaxDesktopFileSize = 10485760;  // 10 MB
// Group name for the main entry we want.
constexpr char kDesktopEntryGroupName[] = "Desktop Entry";
// File extension for desktop files.
constexpr char kDesktopFileExtension[] = ".desktop";
// Desktop path start delimiter for constructing application IDs.
constexpr char kDesktopPathStartDelimiter[] = "applications";
// Key names for the fields we care about.
constexpr char kDesktopEntryType[] = "Type";
constexpr char kDesktopEntryName[] = "Name";
constexpr char kDesktopEntryNameWithLocale[] = "Name[";
constexpr char kDesktopEntryNoDisplay[] = "NoDisplay";
constexpr char kDesktopEntryComment[] = "Comment";
constexpr char kDesktopEntryCommentWithLocale[] = "Comment[";
constexpr char kDesktopEntryIcon[] = "Icon";
constexpr char kDesktopEntryHidden[] = "Hidden";
constexpr char kDesktopEntryOnlyShowIn[] = "OnlyShowIn";
constexpr char kDesktopEntryNotShowIn[] = "NotShowIn";
constexpr char kDesktopEntryTryExec[] = "TryExec";
constexpr char kDesktopEntryExec[] = "Exec";
constexpr char kDesktopEntryPath[] = "Path";
constexpr char kDesktopEntryTerminal[] = "Terminal";
constexpr char kDesktopEntryMimeType[] = "MimeType";
constexpr char kDesktopEntryKeywords[] = "Keywords";
constexpr char kDesktopEntryKeywordsWithLocale[] = "Keywords[";
constexpr char kDesktopEntryCategories[] = "Categories";
constexpr char kDesktopEntryStartupWmClass[] = "StartupWMClass";
constexpr char kDesktopEntryStartupNotify[] = "StartupNotify";
constexpr char kDesktopEntryTypeApplication[] = "Application";
// Valid values for the "Type" entry.
const char* const kValidDesktopEntryTypes[] = {kDesktopEntryTypeApplication,
                                               "Link", "Directory"};
constexpr char kXdgDataDirsEnvVar[] = "XDG_DATA_DIRS";
// Default path to to use if the XDG_DATA_DIRS env var is not set.
constexpr char kDefaultDesktopFilesPath[] = "/usr/share";
constexpr char kSettingsCategory[] = "Settings";
constexpr char kPathEnvVar[] = "PATH";
// For the purpose of determining apps relevant to our desktop env, pretend we
// are a gnome desktop. See crbug.com/839132 for details.
constexpr char kDesktopType[] = "GNOME";

}  // namespace

namespace vm_tools {
namespace garcon {

// static
std::unique_ptr<DesktopFile> DesktopFile::ParseDesktopFile(
    const base::FilePath& file_path) {
  std::unique_ptr<DesktopFile> retval(new DesktopFile());
  if (!retval->LoadFromFile(file_path)) {
    retval.reset();
  }
  return retval;
}

// static
std::vector<base::FilePath> DesktopFile::GetPathsForDesktopFiles() {
  const char* xdg_data_dirs = getenv(kXdgDataDirsEnvVar);
  if (!xdg_data_dirs || strlen(xdg_data_dirs) == 0) {
    xdg_data_dirs = kDefaultDesktopFilesPath;
  }
  // Now break it up into the paths that we should search.
  std::vector<base::StringPiece> search_dirs = base::SplitStringPiece(
      xdg_data_dirs, ":", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
  std::vector<base::FilePath> retval;
  for (const auto& curr_dir : search_dirs) {
    base::FilePath curr_path(curr_dir);
    retval.emplace_back(curr_path.Append(kDesktopPathStartDelimiter));
  }
  return retval;
}

// static
base::FilePath DesktopFile::FindFileForDesktopId(
    const std::string& desktop_id) {
  if (desktop_id.empty()) {
    return base::FilePath();
  }
  // First we need to create the relative path that corresponds to this ID. This
  // is done by replacing all dash chars with the path separator and then
  // appending the .desktop file extension to the name. Alternatively, we also
  // look without doing any replacing.
  std::string rel_path1;
  base::ReplaceChars(desktop_id, "-", "/", &rel_path1);
  rel_path1 += kDesktopFileExtension;
  std::string rel_paths[] = {rel_path1, desktop_id + kDesktopFileExtension};

  std::vector<base::FilePath> search_paths = GetPathsForDesktopFiles();
  for (const auto& curr_path : search_paths) {
    for (const auto& rel_path : rel_paths) {
      base::FilePath test_path = curr_path.Append(rel_path);
      if (base::PathExists(test_path)) {
        return test_path;
      }
    }
  }
  return base::FilePath();
}

bool DesktopFile::LoadFromFile(const base::FilePath& file_path) {
  // First read in the file as a string.
  std::string desktop_contents;
  if (!ReadFileToStringWithMaxSize(file_path, &desktop_contents,
                                   kMaxDesktopFileSize)) {
    LOG(ERROR) << "Failed reading in desktop file: " << file_path.value();
    return false;
  }
  file_path_ = file_path;

  std::vector<base::StringPiece> desktop_lines = base::SplitStringPiece(
      desktop_contents, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);

  // Go through the file line by line, we are looking for the section marked:
  // [Desktop Entry]
  bool in_entry = false;
  for (const auto& curr_line : desktop_lines) {
    if (curr_line.front() == '#') {
      // Skip comment lines.
      continue;
    }
    if (curr_line.front() == '[') {
      if (in_entry) {
        // We only care about the main entry, so terminate parsing if we have
        // found it.
        break;
      }
      // Group name.
      base::StringPiece group_name = ParseGroupName(curr_line);
      if (group_name.empty()) {
        continue;
      }
      if (group_name == kDesktopEntryGroupName) {
        in_entry = true;
      }
    } else if (!in_entry) {
      // We are not in the main entry, and this line doesn't begin that entry so
      // skip it.
      continue;
    } else {
      // Parse the key/value pair on this line for the desktop entry.
      std::pair<std::string, std::string> key_value =
          ExtractKeyValuePair(curr_line);
      if (key_value.second.empty()) {
        // Invalid key/value pair since there was no delimiter, skip this line.
        continue;
      }
      // Check for matching names against all the keys. For the ones that can
      // have a locale in the key name, do those last since we do a startsWith
      // comparison on those.
      std::string key = key_value.first;
      if (key == kDesktopEntryType) {
        entry_type_ = key_value.second;
      } else if (key == kDesktopEntryName) {
        locale_name_map_[""] = UnescapeString(key_value.second);
      } else if (key == kDesktopEntryNoDisplay) {
        no_display_ = ParseBool(key_value.second);
      } else if (key == kDesktopEntryComment) {
        locale_comment_map_[""] = UnescapeString(key_value.second);
      } else if (key == kDesktopEntryIcon) {
        icon_ = key_value.second;
      } else if (key == kDesktopEntryHidden) {
        hidden_ = ParseBool(key_value.second);
      } else if (key == kDesktopEntryOnlyShowIn) {
        ParseMultiString(key_value.second, &only_show_in_);
      } else if (key == kDesktopEntryNotShowIn) {
        ParseMultiString(key_value.second, &not_show_in_);
      } else if (key == kDesktopEntryTryExec) {
        try_exec_ = UnescapeString(key_value.second);
      } else if (key == kDesktopEntryExec) {
        exec_ = UnescapeString(key_value.second);
      } else if (key == kDesktopEntryPath) {
        path_ = UnescapeString(key_value.second);
      } else if (key == kDesktopEntryTerminal) {
        terminal_ = ParseBool(key_value.second);
      } else if (key == kDesktopEntryMimeType) {
        ParseMultiString(key_value.second, &mime_types_);
      } else if (key == kDesktopEntryKeywords) {
        ParseMultiString(key_value.second, &locale_keywords_map_[""]);
      } else if (key == kDesktopEntryCategories) {
        ParseMultiString(key_value.second, &categories_);
      } else if (key == kDesktopEntryStartupWmClass) {
        startup_wm_class_ = UnescapeString(key_value.second);
      } else if (key == kDesktopEntryStartupNotify) {
        startup_notify_ = ParseBool(key_value.second);
      } else if (base::StartsWith(key, kDesktopEntryNameWithLocale,
                                  base::CompareCase::SENSITIVE)) {
        std::string locale = ExtractKeyLocale(key);
        if (locale.empty()) {
          continue;
        }
        locale_name_map_[locale] = UnescapeString(key_value.second);
      } else if (base::StartsWith(key, kDesktopEntryCommentWithLocale,
                                  base::CompareCase::SENSITIVE)) {
        std::string locale = ExtractKeyLocale(key);
        if (locale.empty()) {
          continue;
        }
        locale_comment_map_[locale] = UnescapeString(key_value.second);
      } else if (base::StartsWith(key, kDesktopEntryKeywordsWithLocale,
                                  base::CompareCase::SENSITIVE)) {
        std::string locale = ExtractKeyLocale(key);
        if (locale.empty()) {
          continue;
        }
        ParseMultiString(key_value.second, &locale_keywords_map_[locale]);
      }
    }
  }

  // Validate that the desktop file has the required entries in it.
  // First check the Type key.
  bool valid_type_found = false;
  for (const char* valid_type : kValidDesktopEntryTypes) {
    if (entry_type_ == valid_type) {
      valid_type_found = true;
      break;
    }
  }
  if (!valid_type_found) {
    LOG(ERROR) << "Failed parsing desktop file " << file_path.value()
               << " due to invalid Type key of: " << entry_type_;
    return false;
  }
  // Now check for a valid name.
  if (locale_name_map_.find("") == locale_name_map_.end()) {
    LOG(ERROR) << "Failed parsing desktop file " << file_path.value()
               << " due to missing unlocalized Name entry";
    return false;
  }
  // Since it's valid, set the ID based on the path name. This is done by
  // taking all the path values after "applications" in the path, appending them
  // with dash separators and then removing the .desktop extension from the
  // actual filename.
  // First verify this was actually a .desktop file.
  if (file_path.FinalExtension() != kDesktopFileExtension) {
    LOG(ERROR) << "Failed parsing desktop file due to invalid file extension: "
               << file_path.value();
    return false;
  }
  std::vector<std::string> path_comps;
  file_path.RemoveFinalExtension().GetComponents(&path_comps);
  bool found_path_delim = false;
  for (const auto& comp : path_comps) {
    if (!found_path_delim) {
      found_path_delim = (comp == kDesktopPathStartDelimiter);
      continue;
    }
    if (!app_id_.empty()) {
      app_id_.push_back('-');
    }
    app_id_.append(comp);
  }

  return true;
}

std::vector<std::string> DesktopFile::GenerateArgvWithFiles(
    const std::vector<std::string>& app_args) const {
  std::vector<std::string> retval;
  if (exec_.empty()) {
    return retval;
  }
  // We have already unescaped this string, which we are supposed to do first
  // according to the spec. We need to process this to handle quoted arguments
  // and also field code substitution.
  std::string curr_arg;
  bool in_quotes = false;
  bool next_escaped = false;
  bool next_field_code = false;
  for (auto c : exec_) {
    if (next_escaped) {
      next_escaped = false;
      curr_arg.push_back(c);
      continue;
    }
    if (c == '"') {
      if (in_quotes && !curr_arg.empty()) {
        // End of a quoted argument.
        retval.emplace_back(std::move(curr_arg));
        curr_arg.clear();
      }
      in_quotes = !in_quotes;
      continue;
    }
    if (in_quotes) {
      // There is no field expansion inside quotes, so just append the char
      // unless we have escaping. We only deal with escaping inside of quoted
      // strings here.
      if (c == '\\') {
        next_escaped = true;
        continue;
      }
      curr_arg.push_back(c);
      continue;
    }
    if (next_field_code) {
      next_field_code = false;
      if (c == '%') {
        // Escaped percent sign (I don't know why they just didn't use backslash
        // for escaping percent).
        curr_arg.push_back(c);
        continue;
      }
      switch (c) {
        case 'u':  // Single URL field code.
        case 'f':  // Single file field code.
          if (!app_args.empty()) {
            curr_arg.append(app_args.front());
          }
          continue;
        case 'U':  // Multiple URLs field code.
        case 'F':  // Multiple files field code.
          // For multi-args, the spec is explicit that each file is passed as
          // a separate arg to the program and that %U and %F must only be
          // used as an argument on their own, so complete any active arg
          // that we may have been parsing.
          if (!curr_arg.empty()) {
            retval.emplace_back(std::move(curr_arg));
            curr_arg.clear();
          }
          if (!app_args.empty()) {
            retval.insert(retval.end(), app_args.begin(), app_args.end());
          }
          continue;
        case 'i':  // Icon field code, expands to 2 args.
          if (!curr_arg.empty()) {
            retval.emplace_back(std::move(curr_arg));
            curr_arg.clear();
          }
          if (!icon_.empty()) {
            retval.emplace_back("--icon");
            retval.emplace_back(icon_);
          }
          continue;
        case 'c':  // Translated app name.
          // TODO(jkardatzke): Determine the proper localized name for the app.
          // We enforce that this key exists when we populate the object.
          curr_arg.append(locale_name_map_.find("")->second);
          continue;
        case 'k':  // Path to the desktop file itself.
          curr_arg.append(file_path_.value());
          continue;
        default:  // Unrecognized/deprecated field code. Unrecognized ones are
                  // technically invalid, but it seems better to just ignore
                  // them then completely abort executing this desktop file.
          continue;
      }
    }
    if (c == ' ') {
      // Argument separator.
      if (!curr_arg.empty()) {
        retval.emplace_back(std::move(curr_arg));
        curr_arg.clear();
      }
      continue;
    }
    if (c == '%') {
      next_field_code = true;
      continue;
    }
    curr_arg.push_back(c);
  }
  if (!curr_arg.empty()) {
    retval.emplace_back(std::move(curr_arg));
  }
  return retval;
}

std::string DesktopFile::GenerateExecutableFileName() const {
  std::vector<std::string> ArgvWithFiles = GenerateArgvWithFiles({});
  if (ArgvWithFiles.empty())
    return "";
  return base::FilePath(ArgvWithFiles.at(0)).BaseName().MaybeAsASCII();
}

bool DesktopFile::ShouldPassToHost() const {
  // Rules to follow:
  // -Only allow Applications.
  // -Don't pass hidden.
  // -Don't pass without an exec entry.
  // -Don't pass no_display that also have no mime types.
  // -Don't pass terminal apps (e.g. apps that run in a terminal like vim).
  // -Don't pass if in the Settings category.
  // -Don't pass if OnlyShowIn exists and doesn't contain kDesktopType.
  // -Don't pass if NotShowIn exists and contains kDesktopType.
  // -Don't pass if TryExec doesn't resolve to a valid executable file.
  if (!IsApplication() || hidden_ || exec_.empty() ||
      (no_display_ && mime_types_.empty()) || terminal_) {
    return false;
  }

  if (std::find(categories_.begin(), categories_.end(), kSettingsCategory) !=
      categories_.end()) {
    return false;
  }

  if (!only_show_in_.empty() &&
      std::find(only_show_in_.begin(), only_show_in_.end(), kDesktopType) ==
          only_show_in_.end()) {
    return false;
  }

  if (!not_show_in_.empty() &&
      std::find(not_show_in_.begin(), not_show_in_.end(), kDesktopType) !=
          not_show_in_.end()) {
    return false;
  }

  if (!try_exec_.empty()) {
    // If it's absolute, we just check it the way it is.
    base::FilePath try_exec_path(try_exec_);
    if (try_exec_path.IsAbsolute()) {
      int permissions;
      if (!base::GetPosixFilePermissions(try_exec_path, &permissions) ||
          !(permissions & base::FILE_PERMISSION_EXECUTE_BY_USER)) {
        return false;
      }
    } else {
      // Search the system path instead.
      std::string path;
      if (!base::Environment::Create()->GetVar(kPathEnvVar, &path)) {
        // If there's no PATH set we can't search.
        return false;
      }
      bool found_match = false;
      for (const base::StringPiece& cur_path : base::SplitStringPiece(
               path, ":", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) {
        base::FilePath file(cur_path);
        int permissions;
        if (base::GetPosixFilePermissions(file.Append(try_exec_),
                                          &permissions) &&
            (permissions & base::FILE_PERMISSION_EXECUTE_BY_USER)) {
          found_match = true;
          break;
        }
      }
      if (!found_match) {
        return false;
      }
    }
  }

  return true;
}

bool DesktopFile::IsApplication() const {
  return entry_type_ == kDesktopEntryTypeApplication;
}

}  // namespace garcon
}  // namespace vm_tools
