//
// Copyright (C) 2009 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/common/mock_http_fetcher.h"

#include <algorithm>

#include <base/bind.h>
#include <base/logging.h>
#include <base/strings/string_util.h>
#include <base/time/time.h>
#include <brillo/message_loops/message_loop.h>
#include <gtest/gtest.h>

// This is a mock implementation of HttpFetcher which is useful for testing.

using brillo::MessageLoop;
using std::min;

namespace chromeos_update_engine {

MockHttpFetcher::~MockHttpFetcher() {
  CHECK(timeout_id_ == MessageLoop::kTaskIdNull)
      << "Call TerminateTransfer() before dtor.";
}

void MockHttpFetcher::BeginTransfer(const std::string& url) {
  EXPECT_FALSE(never_use_);
  if (fail_transfer_ || data_.empty()) {
    // No data to send, just notify of completion..
    SignalTransferComplete();
    return;
  }
  if (sent_offset_ < data_.size())
    SendData(true);
}

void MockHttpFetcher::SendData(bool skip_delivery) {
  if (fail_transfer_ || sent_offset_ == data_.size()) {
    SignalTransferComplete();
    return;
  }

  if (paused_) {
    // If we're paused, we should return so no callback is scheduled.
    return;
  }

  // Setup timeout callback even if the transfer is about to be completed in
  // order to get a call to |TransferComplete|.
  if (timeout_id_ == MessageLoop::kTaskIdNull && delay_) {
    CHECK(MessageLoop::current());
    timeout_id_ = MessageLoop::current()->PostDelayedTask(
        FROM_HERE,
        base::Bind(&MockHttpFetcher::TimeoutCallback, base::Unretained(this)),
        base::TimeDelta::FromMilliseconds(10));
  }

  if (!skip_delivery || !delay_) {
    const size_t chunk_size =
        min(kMockHttpFetcherChunkSize, data_.size() - sent_offset_);
    sent_offset_ += chunk_size;
    bytes_sent_ += chunk_size;
    CHECK(delegate_);
    delegate_->ReceivedBytes(
        this, &data_[sent_offset_ - chunk_size], chunk_size);
  }
  // We may get terminated and deleted right after |ReceivedBytes| call, so we
  // should not access any class member variable after this call.
}

void MockHttpFetcher::TimeoutCallback() {
  CHECK(!paused_);
  timeout_id_ = MessageLoop::kTaskIdNull;
  CHECK_LE(sent_offset_, data_.size());
  // Same here, we should not access any member variable after this call.
  SendData(false);
}

// If the transfer is in progress, aborts the transfer early.
// The transfer cannot be resumed.
void MockHttpFetcher::TerminateTransfer() {
  LOG(INFO) << "Terminating transfer.";
  // During testing, MessageLoop may or may not be available.
  // So don't call CancelTask() unless necessary.
  if (timeout_id_ != MessageLoop::kTaskIdNull) {
    MessageLoop::current()->CancelTask(timeout_id_);
    timeout_id_ = MessageLoop::kTaskIdNull;
  }
  if (delegate_) {
    delegate_->TransferTerminated(this);
  }
}

void MockHttpFetcher::SetHeader(const std::string& header_name,
                                const std::string& header_value) {
  extra_headers_[base::ToLowerASCII(header_name)] = header_value;
}

std::string MockHttpFetcher::GetHeader(const std::string& header_name) const {
  const auto it = extra_headers_.find(base::ToLowerASCII(header_name));
  if (it == extra_headers_.end())
    return "";
  return it->second;
}

void MockHttpFetcher::Pause() {
  CHECK(!paused_);
  paused_ = true;
  MessageLoop::current()->CancelTask(timeout_id_);
  timeout_id_ = MessageLoop::kTaskIdNull;
}

void MockHttpFetcher::Unpause() {
  CHECK(paused_) << "You must pause before unpause.";
  paused_ = false;
  SendData(false);
}

void MockHttpFetcher::FailTransfer(int http_response_code) {
  fail_transfer_ = true;
  http_response_code_ = http_response_code;
}

void MockHttpFetcher::SignalTransferComplete() {
  // If the transfer has been failed, the HTTP response code should be set
  // already.
  if (!fail_transfer_) {
    http_response_code_ = 200;
  }
  delegate_->TransferComplete(this, !fail_transfer_);
}

}  // namespace chromeos_update_engine
