//
// Copyright (C) 2012 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include "update_engine/omaha_request_action.h"

#include <inttypes.h>

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

#include <base/bind.h>
#include <base/logging.h>
#include <base/rand_util.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_util.h>
#include <base/strings/string_split.h>
#include <base/strings/stringprintf.h>
#include <base/strings/string_number_conversions.h>
#include <base/time/time.h>
#include <expat.h>
#include <metrics/metrics_library.h>

#include "update_engine/common/action_pipe.h"
#include "update_engine/common/constants.h"
#include "update_engine/common/hardware_interface.h"
#include "update_engine/common/hash_calculator.h"
#include "update_engine/common/platform_constants.h"
#include "update_engine/common/prefs_interface.h"
#include "update_engine/common/utils.h"
#include "update_engine/connection_manager_interface.h"
#include "update_engine/metrics.h"
#include "update_engine/metrics_utils.h"
#include "update_engine/p2p_manager.h"
#include "update_engine/payload_state_interface.h"
#include "update_engine/payload_properties_request_action.h"

#define HAS_KEY(x, y) ((x).find((y)) != (x).end())

namespace chromeos_update_engine {

using std::string;
using std::pair;
using std::vector;

PayloadPropertiesRequestAction::PayloadPropertiesRequestAction(
    SystemState* system_state,
    PayloadProperties *properties,
    HttpFetcher *http_fetcher)
    : system_state_(system_state),
      properties_(properties),
      http_fetcher_(http_fetcher)
{
}

PayloadPropertiesRequestAction::~PayloadPropertiesRequestAction() {}

void PayloadPropertiesRequestAction::PerformAction() {
  http_fetcher_->set_delegate(this);

  // we support only one URL for now
  CHECK(properties_->payload_urls.size() == 1);

  LOG(INFO) << "URL: " << properties_->payload_urls[0];
  http_fetcher_->BeginTransfer(properties_->payload_urls[0]);
}

void PayloadPropertiesRequestAction::TerminateProcessing() {
  http_fetcher_->TerminateTransfer();
}

// We just store the response in the buffer. Once we've received all bytes,
// we'll look in the buffer and decide what to do.
void PayloadPropertiesRequestAction::ReceivedBytes(HttpFetcher *fetcher,
                                       const void* bytes,
                                       size_t length) {
  const uint8_t* byte_ptr = reinterpret_cast<const uint8_t*>(bytes);
  response_buffer_.insert(response_buffer_.end(), byte_ptr, byte_ptr + length);
}

// If the transfer was successful, this uses expat to parse the response
// and fill in the appropriate fields of the output object. Also, notifies
// the processor that we're done.
void PayloadPropertiesRequestAction::TransferComplete(HttpFetcher *fetcher,
                                          bool successful) {
  ScopedActionCompleter completer(processor_, this);

  if (!successful) {
    LOG(ERROR) << "Payload properties network transfer failed.";
    int code = GetHTTPResponseCode();
    // Makes sure we send sane error values.
    if (code < 0 || code >= 1000) {
      code = 999;
    }
    completer.set_code(static_cast<ErrorCode>(
        static_cast<int>(ErrorCode::kHTTPResponseBase) + code));
    return;
  }

  auto prop_end = std::find(response_buffer_.begin(), response_buffer_.end(), 0);
  vector<pair<string, string>> kv_pairs;
  std::map<string, string> kv_map;
  if (!base::SplitStringIntoKeyValuePairs(string(response_buffer_.begin(), prop_end),
                ' ', '\n', &kv_pairs))
  {
    LOG(ERROR) << "Can't parse Payload properties";
    return;
  }
  std::copy(kv_pairs.begin(), kv_pairs.end(),
                std::inserter(kv_map, kv_map.begin()));

  if (!HAS_KEY(kv_map, "FILE_SIZE:") ||
      !base::StringToInt64(kv_map.at("FILE_SIZE:"), &properties_->size))
  {
    LOG(ERROR) << "Can't get FILE_SIZE from Payload properties: ";
    return;
  }
  if (!HAS_KEY(kv_map, "METADATA_SIZE:") ||
      !base::StringToInt64(kv_map.at("METADATA_SIZE:"), &properties_->metadata_size))
  {
    LOG(ERROR) << "Can't get METADATA_SIZE from Payload properties: ";
    return;
  }
  if (!HAS_KEY(kv_map, "FILE_HASH:"))
  {
    LOG(ERROR) << "Can't get FILE_HASH from Payload properties: ";
    return;
  }
  properties_->hash = kv_map["FILE_HASH:"];
  if (!HAS_KEY(kv_map, "Larry-app-version:"))
  {
    LOG(ERROR) << "Can't get Larry-app-version from Payload properties: ";
    return;
  }
  properties_->version = kv_map["Larry-app-version:"];

  properties_->update_exists = true;

  system_state_->payload_state()->SetResponse(*properties_);

  if (HasOutputPipe())
      SetOutputObject(*properties_);
  completer.set_code(ErrorCode::kSuccess);

  // TODO add more properties to be able to recover update after crash or reboot
}

void PayloadPropertiesRequestAction::ActionCompleted(ErrorCode code)
{
  metrics::CheckResult result = metrics::CheckResult::kUnset;
  metrics::CheckReaction reaction = metrics::CheckReaction::kUnset;
  metrics::DownloadErrorCode download_error_code =
      metrics::DownloadErrorCode::kUnset;

  // Regular update attempt.
  switch (code) {
  case ErrorCode::kSuccess:
    // OK, we parsed the response successfully but that does
    // necessarily mean that an update is available.
    if (HasOutputPipe()) {
        result = metrics::CheckResult::kUpdateAvailable;
        reaction = metrics::CheckReaction::kUpdating;
    } else {
      result = metrics::CheckResult::kNoUpdateAvailable;
    }
    break;

  default:
    // We report two flavors of errors, "Download errors" and "Parsing
    // error". Try to convert to the former and if that doesn't work
    // we know it's the latter.
    metrics::DownloadErrorCode tmp_error =
        metrics_utils::GetDownloadErrorCode(code);
    if (tmp_error != metrics::DownloadErrorCode::kInputMalformed) {
      result = metrics::CheckResult::kDownloadError;
      download_error_code = tmp_error;
    } else {
      result = metrics::CheckResult::kParsingError;
    }
    break;
  }

  metrics::ReportUpdateCheckMetrics(system_state_,
                                    result, reaction, download_error_code);
}

}  // namespace chromeos_update_engine
