// Copyright (c) 2011 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 "update_engine/omaha_request_params.h"

#include <errno.h>
#include <fcntl.h>
#include <sys/utsname.h>

#include <map>
#include <string>
#include <vector>

#include <base/file_util.h>
#include <policy/device_policy.h>

#include "update_engine/simple_key_value_store.h"
#include "update_engine/utils.h"

#define CALL_MEMBER_FN(object, member) ((object).*(member))

using std::map;
using std::string;
using std::vector;

namespace chromeos_update_engine {

const char* const OmahaRequestParams::kAppId(
    "{87efface-864d-49a5-9bb3-4b050a7c227a}");
const char* const OmahaRequestParams::kOsPlatform("Chrome OS");
const char* const OmahaRequestParams::kOsVersion("Indy");
const char* const kProductionOmahaUrl(
    "https://tools.google.com/service/update2");

const char OmahaRequestParams::kUpdateTrackKey[] = "CHROMEOS_RELEASE_TRACK";

OmahaRequestDeviceParams::OmahaRequestDeviceParams() :
    force_lock_down_(false),
    forced_lock_down_(false) {}

bool OmahaRequestDeviceParams::Init(const std::string& in_app_version,
                                    const std::string& in_update_url,
                                    const std::string& in_release_track,
                                    bool in_interactive) {
  bool stateful_override = !ShouldLockDown();
  os_platform = OmahaRequestParams::kOsPlatform;
  os_version = OmahaRequestParams::kOsVersion;
  app_version = in_app_version.empty() ?
      GetLsbValue("CHROMEOS_RELEASE_VERSION", "", NULL, stateful_override) :
      in_app_version;
  os_sp = app_version + "_" + GetMachineType();
  os_board = GetLsbValue("CHROMEOS_RELEASE_BOARD", "", NULL, stateful_override);
  app_id = GetLsbValue("CHROMEOS_RELEASE_APPID",
                       OmahaRequestParams::kAppId,
                       NULL,
                       stateful_override);
  app_lang = "en-US";

  // Determine the release track if it wasn't specified by the caller.
  if (in_release_track.empty() || !IsValidTrack(in_release_track)) {
    app_track = GetLsbValue(
        kUpdateTrackKey,
        "",
        &chromeos_update_engine::OmahaRequestDeviceParams::IsValidTrack,
        true);  // stateful_override
  } else {
    app_track = in_release_track;
  }

  hardware_class = utils::GetHardwareClass();
  struct stat stbuf;

  // Deltas are only okay if the /.nodelta file does not exist.  If we don't
  // know (i.e. stat() returns some unexpected error), then err on the side of
  // caution and say deltas are not okay.
  delta_okay = (stat((root_ + "/.nodelta").c_str(), &stbuf) < 0) &&
               (errno == ENOENT);

  // For now, disable delta updates if the rootfs track is different than the
  // track that we're sending to the update server because such updates are
  // destined to fail -- the source rootfs hash will be different than the
  // expected hash due to the different track in /etc/lsb-release.
  //
  // Longer term we should consider an alternative: (a) clients can send
  // (current_version, current_channel, new_channel) information, or (b) the
  // build process can make sure releases on separate tracks are identical (i.e,
  // by not stamping the release with the channel), or (c) the release process
  // can ensure that different channels get different version numbers.
  const string rootfs_track = GetLsbValue(
      kUpdateTrackKey,
      "",
      NULL,  // No need to validate the read-only rootfs track.
      false);  // stateful_override
  delta_okay = delta_okay && rootfs_track == app_track;

  update_url = in_update_url.empty() ?
      GetLsbValue("CHROMEOS_AUSERVER",
                  kProductionOmahaUrl,
                  NULL,
                  stateful_override) :
      in_update_url;

  // Set the interactive flag accordingly.
  interactive = in_interactive;

  return true;
}

bool OmahaRequestDeviceParams::SetTrack(const std::string& track) {
  TEST_AND_RETURN_FALSE(IsValidTrack(track));
  FilePath kFile(root_ + utils::kStatefulPartition + "/etc/lsb-release");
  string file_data;
  map<string, string> data;
  if (file_util::ReadFileToString(kFile, &file_data)) {
    data = simple_key_value_store::ParseString(file_data);
  }
  data[kUpdateTrackKey] = track;
  file_data = simple_key_value_store::AssembleString(data);
  TEST_AND_RETURN_FALSE(file_util::CreateDirectory(kFile.DirName()));
  TEST_AND_RETURN_FALSE(
      file_util::WriteFile(kFile, file_data.data(), file_data.size()) ==
      static_cast<int>(file_data.size()));
  app_track = track;
  return true;
}

bool OmahaRequestDeviceParams::SetDeviceTrack(const std::string& track) {
  OmahaRequestDeviceParams params;
  TEST_AND_RETURN_FALSE(params.Init("", "", "", false));
  return params.SetTrack(track);
}

string OmahaRequestDeviceParams::GetDeviceTrack() {
  OmahaRequestDeviceParams params;
  // Note that params.app_track is an empty string if the value in
  // lsb-release file is invalid. See Init() for details.
  return params.Init("", "", "", false) ? params.app_track : "";
}

string OmahaRequestDeviceParams::GetLsbValue(const string& key,
                                             const string& default_value,
                                             ValueValidator validator,
                                             bool stateful_override) const {
  vector<string> files;
  if (stateful_override) {
    files.push_back(string(utils::kStatefulPartition) + "/etc/lsb-release");
  }
  files.push_back("/etc/lsb-release");
  for (vector<string>::const_iterator it = files.begin();
       it != files.end(); ++it) {
    // TODO(adlr): make sure files checked are owned as root (and all their
    // parents are recursively, too).
    string file_data;
    if (!utils::ReadFile(root_ + *it, &file_data))
      continue;

    map<string, string> data = simple_key_value_store::ParseString(file_data);
    if (utils::MapContainsKey(data, key)) {
      const string& value = data[key];
      if (validator && !CALL_MEMBER_FN(*this, validator)(value)) {
        continue;
      }
      return value;
    }
  }
  // not found
  return default_value;
}

string OmahaRequestDeviceParams::GetMachineType() const {
  struct utsname buf;
  string ret;
  if (uname(&buf) == 0)
    ret = buf.machine;
  return ret;
}

bool OmahaRequestDeviceParams::ShouldLockDown() const {
  if (force_lock_down_) {
    return forced_lock_down_;
  }
  return utils::IsOfficialBuild() && utils::IsNormalBootMode();
}

bool OmahaRequestDeviceParams::IsValidTrack(const std::string& track) const {
  static const char* kValidTracks[] = {
    "beta-channel",
    "canary-channel",
    "dev-channel",
    "dogfood-channel",
    "stable-channel",
  };
  if (!ShouldLockDown()) {
    return true;
  }
  for (size_t t = 0; t < arraysize(kValidTracks); ++t) {
    if (track == kValidTracks[t]) {
      return true;
    }
  }
  return false;
}

void OmahaRequestDeviceParams::SetLockDown(bool lock) {
  force_lock_down_ = true;
  forced_lock_down_ = lock;
}

}  // namespace chromeos_update_engine
