// Copyright 2021 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/setup/arc_property_util.h"

#include <algorithm>
#include <tuple>
#include <vector>

#include <base/command_line.h>
#include <base/files/file_util.h>
#include <base/json/json_reader.h>
#include <base/logging.h>
#include <base/process/launch.h>
#include <base/strings/string_split.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <chromeos-config/libcros_config/cros_config.h>

namespace arc {
namespace {

// The path in the chromeos-config database where Android properties will be
// looked up.
constexpr char kCrosConfigPropertiesPath[] = "/arc/build-properties";

// Android property name used to store the board name.
constexpr char kBoardPropertyPrefix[] = "ro.product.board=";

// Android property name for custom key used for Play Auto Install selection.
constexpr char kOEMKey1PropertyPrefix[] = "ro.oem.key1=";

// Configuration property name of an optional string that contains a comma-
// separated list of regions to include in the OEM key property.
constexpr char kPAIRegionsPropertyName[] = "pai-regions";

// Properties related to dynamically adding native bridge 64 bit support.
// Note that "%s" is lated replaced with a partition name which is either an
// empty string or a string that ends with '.' e.g. "system_ext.".
constexpr char kAbilistPropertyPrefixTemplate[] = "ro.%sproduct.cpu.abilist=";
constexpr char kAbilistPropertyExpected[] = "x86_64,x86,armeabi-v7a,armeabi";
constexpr char kAbilistPropertyReplacement[] =
    "x86_64,x86,arm64-v8a,armeabi-v7a,armeabi";
constexpr char kAbilist64PropertyPrefixTemplate[] =
    "ro.%sproduct.cpu.abilist64=";
constexpr char kAbilist64PropertyExpected[] = "x86_64";
constexpr char kAbilist64PropertyReplacement[] = "x86_64,arm64-v8a";
constexpr char kDalvikVmIsaArm64[] = "ro.dalvik.vm.isa.arm64=x86_64";

// Prefix of Android property to enable debugging features.
constexpr char kDebuggablePropertyPrefix[] = "ro.debuggable=";

// Maximum length of an Android property value.
constexpr int kAndroidMaxPropertyLength = 91;

bool FindProperty(const std::string& line_prefix_to_find,
                  std::string* out_prop,
                  const std::string& line) {
  if (base::StartsWith(line, line_prefix_to_find,
                       base::CompareCase::SENSITIVE)) {
    *out_prop = line.substr(line_prefix_to_find.length());
    return true;
  }
  return false;
}

bool TruncateAndroidProperty(const std::string& line, std::string* truncated) {
  // If line looks like key=value, cut value down to the max length of an
  // Android property.  Build fingerprint needs special handling to preserve the
  // trailing dev-keys indicator, but other properties can just be truncated.
  size_t eq_pos = line.find('=');
  if (eq_pos == std::string::npos) {
    *truncated = line;
    return true;
  }

  std::string val = line.substr(eq_pos + 1);
  base::TrimWhitespaceASCII(val, base::TRIM_ALL, &val);
  if (val.length() <= kAndroidMaxPropertyLength) {
    *truncated = line;
    return true;
  }

  const std::string key = line.substr(0, eq_pos);
  LOG(WARNING) << "Truncating property " << key << " value: " << val;
  if (key == "ro.bootimage.build.fingerprint" &&
      base::EndsWith(val, "/dev-keys", base::CompareCase::SENSITIVE)) {
    // Typical format is brand/product/device/.../dev-keys.  We want to remove
    // characters from product and device to get below the length limit.
    // Assume device has the format {product}_cheets.
    std::vector<std::string> fields =
        base::SplitString(val, "/", base::WhitespaceHandling::KEEP_WHITESPACE,
                          base::SplitResult::SPLIT_WANT_ALL);
    if (fields.size() < 5) {
      LOG(ERROR) << "Invalid build fingerprint: " << val;
      return false;
    }

    size_t remove_chars = (val.length() - kAndroidMaxPropertyLength + 1) / 2;
    if (fields[1].length() <= remove_chars) {
      LOG(ERROR) << "Unable to remove " << remove_chars << " characters from "
                 << fields[1];
      return false;
    }
    fields[1] = fields[1].substr(0, fields[1].length() - remove_chars);
    fields[2] = fields[1] + "_cheets";
    val = base::JoinString(fields, "/");
  } else {
    val = val.substr(0, kAndroidMaxPropertyLength);
  }

  *truncated = key + "=" + val;
  return true;
}

// Computes the value of ro.oem.key1 based on the build-time ro.product.board
// value and the device's region of origin.
std::string ComputeOEMKey(brillo::CrosConfigInterface* config,
                          const std::string& board) {
  std::string regions;
  if (!config->GetString(kCrosConfigPropertiesPath, kPAIRegionsPropertyName,
                         &regions)) {
    // No region list found, just use the board name as before.
    return board;
  }

  std::string region_code;
  if (!base::GetAppOutput({"cros_region_data", "region_code"}, &region_code)) {
    LOG(WARNING) << "Failed to get region code";
    return board;
  }

  // Remove trailing newline.
  region_code.erase(std::remove(region_code.begin(), region_code.end(), '\n'),
                    region_code.end());

  // Allow wildcard configuration to indicate that all regions should be
  // included.
  if (regions.compare("*") == 0 && region_code.length() >= 2)
    return board + "_" + region_code;

  // Check to see if region code is in the list of regions that should be
  // included in the property.
  const std::vector<std::string> region_vector =
      base::SplitString(regions, ",", base::WhitespaceHandling::TRIM_WHITESPACE,
                        base::SplitResult::SPLIT_WANT_NONEMPTY);
  for (const auto& region : region_vector) {
    if (region_code.compare(region) == 0)
      return board + "_" + region_code;
  }

  return board;
}

bool IsComment(const std::string& line) {
  return base::StartsWith(
      base::TrimWhitespaceASCII(line, base::TrimPositions::TRIM_LEADING), "#",
      base::CompareCase::SENSITIVE);
}

bool ExpandPropertyContents(const std::string& content,
                            brillo::CrosConfigInterface* config,
                            std::string* expanded_content,
                            bool filter_non_ro_props,
                            bool add_native_bridge_64bit_support,
                            bool append_dalvik_isa,
                            bool debuggable,
                            const std::string& partition_name) {
  const std::vector<std::string> lines = base::SplitString(
      content, "\n", base::WhitespaceHandling::KEEP_WHITESPACE,
      base::SplitResult::SPLIT_WANT_ALL);

  std::string new_properties;
  for (std::string line : lines) {
    // Since Chrome only expands ro. properties at runtime, skip processing
    // non-ro lines here for R+. For P, we cannot do that because the
    // expanded property files will directly replace the original ones via
    // bind mounts.
    if (filter_non_ro_props &&
        !base::StartsWith(line, "ro.", base::CompareCase::SENSITIVE)) {
      if (!IsComment(line) && line.find('{') != std::string::npos) {
        // The non-ro property has substitution(s).
        LOG(ERROR) << "Found substitution(s) in a non-ro property: " << line;
        return false;
      }
      continue;
    }

    // First expand {property} substitutions in the string.  The insertions
    // may contain substitutions of their own, so we need to repeat until
    // nothing more is found.
    bool inserted;
    do {
      inserted = false;
      size_t match_start = line.find('{');
      size_t prev_match = 0;  // 1 char past the end of the previous {} match.
      std::string expanded;
      // Find all of the {} matches on the line.
      while (match_start != std::string::npos) {
        expanded += line.substr(prev_match, match_start - prev_match);

        size_t match_end = line.find('}', match_start);
        if (match_end == std::string::npos) {
          LOG(ERROR) << "Unmatched { found in line: " << line;
          return false;
        }

        const std::string keyword =
            line.substr(match_start + 1, match_end - match_start - 1);
        std::string replacement;
        if (config->GetString(kCrosConfigPropertiesPath, keyword,
                              &replacement)) {
          expanded += replacement;
          inserted = true;
        } else {
          LOG(ERROR) << "Did not find a value for " << keyword
                     << " while expanding " << line;
          return false;
        }

        prev_match = match_end + 1;
        match_start = line.find('{', match_end);
      }
      if (prev_match != std::string::npos)
        expanded += line.substr(prev_match);
      line = expanded;
    } while (inserted);

    if (add_native_bridge_64bit_support) {
      // Special-case ro.<partition>product.cpu.abilist and
      // ro.<partition>product.cpu.abilist64 to add ARM64.
      // Note that <partition> is either an empty string or a string that ends
      // with '.' e.g. "system_ext.".
      std::string prefix = base::StringPrintf(kAbilistPropertyPrefixTemplate,
                                              partition_name.c_str());
      std::string value;
      if (FindProperty(prefix, &value, line)) {
        if (value == kAbilistPropertyExpected) {
          line = prefix + std::string(kAbilistPropertyReplacement);
        } else {
          LOG(ERROR) << "Found unexpected value for " << prefix << ", value "
                     << value;
          return false;
        }
      }
      prefix = base::StringPrintf(kAbilist64PropertyPrefixTemplate,
                                  partition_name.c_str());
      if (FindProperty(prefix, &value, line)) {
        if (value == kAbilist64PropertyExpected) {
          line = prefix + std::string(kAbilist64PropertyReplacement);
        } else {
          LOG(ERROR) << "Found unexpected value for " << prefix << ", value "
                     << value;
          return false;
        }
      }
    }

    {
      // Replace ro.debuggable value with |debuggable| flag.
      const std::string prefix(kDebuggablePropertyPrefix);
      std::string value;
      if (FindProperty(prefix, &value, line)) {
        line = prefix + (debuggable ? "1" : "0");
      }
    }

    std::string truncated;
    if (!TruncateAndroidProperty(line, &truncated)) {
      LOG(ERROR) << "Unable to truncate property: " << line;
      return false;
    }

    new_properties += truncated + "\n";

    // Special-case ro.product.board to compute ro.oem.key1 at runtime, as it
    // can depend upon the device region.
    std::string property;
    if (FindProperty(kBoardPropertyPrefix, &property, line)) {
      std::string oem_key_property = ComputeOEMKey(config, property);
      new_properties +=
          std::string(kOEMKey1PropertyPrefix) + oem_key_property + "\n";
    }
  }

  if (append_dalvik_isa) {
    // Special-case to add ro.dalvik.vm.isa.arm64.
    new_properties += std::string(kDalvikVmIsaArm64) + "\n";
  }

  *expanded_content = new_properties;
  return true;
}

bool ExpandPropertyFile(const base::FilePath& input,
                        const base::FilePath& output,
                        brillo::CrosConfigInterface* config,
                        bool append,
                        bool add_native_bridge_64bit_support,
                        bool append_dalvik_isa,
                        bool debuggable,
                        const std::string& partition_name) {
  std::string content;
  std::string expanded;
  if (!base::ReadFileToString(input, &content)) {
    PLOG(ERROR) << "Failed to read " << input;
    return false;
  }
  if (!ExpandPropertyContents(content, config, &expanded,
                              /*filter_non_ro_props=*/append,
                              add_native_bridge_64bit_support,
                              append_dalvik_isa, debuggable, partition_name)) {
    return false;
  }
  if (append && base::PathExists(output)) {
    if (!base::AppendToFile(output, expanded)) {
      PLOG(ERROR) << "Failed to append to " << output;
      return false;
    }
  } else {
    if (!base::WriteFile(output, expanded)) {
      PLOG(ERROR) << "Failed to write to " << output;
      return false;
    }
  }
  return true;
}

}  // namespace

bool ExpandPropertyContentsForTesting(const std::string& content,
                                      brillo::CrosConfigInterface* config,
                                      bool debuggable,
                                      std::string* expanded_content) {
  return ExpandPropertyContents(content, config, expanded_content,
                                /*filter_non_ro_props=*/true,
                                /*add_native_bridge_64bit_support=*/false,
                                false, debuggable, std::string());
}

bool TruncateAndroidPropertyForTesting(const std::string& line,
                                       std::string* truncated) {
  return TruncateAndroidProperty(line, truncated);
}

bool ExpandPropertyFileForTesting(const base::FilePath& input,
                                  const base::FilePath& output,
                                  brillo::CrosConfigInterface* config) {
  return ExpandPropertyFile(input, output, config, /*append=*/false,
                            /*add_native_bridge_64bit_support=*/false, false,
                            /*debuggable=*/false, std::string());
}

bool ExpandPropertyFiles(const base::FilePath& source_path,
                         const base::FilePath& dest_path,
                         bool single_file,
                         bool add_native_bridge_64bit_support,
                         bool debuggable) {
  brillo::CrosConfig config;
  if (single_file)
    base::DeleteFile(dest_path);

  // default.prop may not exist. Silently skip it if not found.
  for (const auto& tuple :
       // The order has to match the one in PropertyLoadBootDefaults() in
       // system/core/init/property_service.cpp.
       // Note: Our vendor image doesn't have /vendor/default.prop although
       // PropertyLoadBootDefaults() tries to open it.
       {std::tuple<const char*, bool, bool, const char*>{"default.prop", true,
                                                         false, ""},
        {"build.prop", false, true, ""},
        {"system_ext_build.prop", true, false, "system_ext."},
        {"vendor_build.prop", false, false, "vendor."},
        {"odm_build.prop", true, false, "odm."},
        {"product_build.prop", true, false, "product."}}) {
    const char* file = std::get<0>(tuple);
    const bool is_optional = std::get<1>(tuple);
    // When true, unconditionally add |kDalvikVmIsaArm64| property.
    const bool append_dalvik_isa =
        std::get<2>(tuple) && add_native_bridge_64bit_support;
    // Search for ro.<partition_name>product.cpu.abilist* properties.
    const char* partition_name = std::get<3>(tuple);

    const base::FilePath source_file = source_path.Append(file);
    if (is_optional && !base::PathExists(source_file))
      continue;

    if (!ExpandPropertyFile(
            source_file, single_file ? dest_path : dest_path.Append(file),
            &config,
            /*append=*/single_file, add_native_bridge_64bit_support,
            append_dalvik_isa, debuggable, partition_name)) {
      LOG(ERROR) << "Failed to expand " << source_file;
      return false;
    }
  }
  return true;
}

}  // namespace arc
