// Copyright (c) 2010 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.

#ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_MULTI_RANGE_HTTP_FETCHER_H__
#define CHROMEOS_PLATFORM_UPDATE_ENGINE_MULTI_RANGE_HTTP_FETCHER_H__

#include <deque>
#include <utility>
#include <vector>

#include <base/memory/scoped_ptr.h>

#include "update_engine/http_fetcher.h"

// This class is a simple wrapper around an HttpFetcher. The client
// specifies a vector of byte ranges. MultiRangeHttpFetcher will fetch bytes
// from those offsets, using the same bash fetcher for all ranges. Thus, the
// fetcher must support beginning a transfter after one has stopped. Pass -1
// as a length to specify unlimited length. It really only would make sense
// for the last range specified to have unlimited length, tho it is legal for
// other entries to have unlimited length.

// There are three states a MultiRangeHttpFetcher object will be in:
// - Stopped (start state)
// - Downloading
// - Pending transfer ended
// Various functions below that might change state indicate possible
// state changes.

namespace chromeos_update_engine {

class MultiRangeHttpFetcher : public HttpFetcher, public HttpFetcherDelegate {
 public:
  // Takes ownership of the passed in fetcher.
  explicit MultiRangeHttpFetcher(HttpFetcher* base_fetcher)
      : HttpFetcher(base_fetcher->proxy_resolver()),
        base_fetcher_(base_fetcher),
        base_fetcher_active_(false),
        pending_transfer_ended_(false),
        terminating_(false),
        current_index_(0),
        bytes_received_this_range_(0) {}
  ~MultiRangeHttpFetcher() {}

  void ClearRanges() { ranges_.clear(); }

  void AddRange(off_t offset, size_t size) {
    CHECK_GT(size, static_cast<size_t>(0));
    ranges_.push_back(Range(offset, size));
  }

  void AddRange(off_t offset) {
    ranges_.push_back(Range(offset));
  }

  virtual void SetOffset(off_t offset) {}  // for now, doesn't support this

  virtual void SetLength(size_t length) {}  // unsupported
  virtual void UnsetLength() {}

  // Begins the transfer to the specified URL.
  // State change: Stopped -> Downloading
  // (corner case: Stopped -> Stopped for an empty request)
  virtual void BeginTransfer(const std::string& url);

  // State change: Downloading -> Pending transfer ended
  virtual void TerminateTransfer();

  virtual void Pause() { base_fetcher_->Pause(); }

  virtual void Unpause() { base_fetcher_->Unpause(); }

  // These functions are overloaded in LibcurlHttp fetcher for testing purposes.
  virtual void set_idle_seconds(int seconds) {
    base_fetcher_->set_idle_seconds(seconds);
  }
  virtual void set_retry_seconds(int seconds) {
    base_fetcher_->set_retry_seconds(seconds);
  }
  virtual void SetConnectionAsExpensive(bool is_expensive) {
    base_fetcher_->SetConnectionAsExpensive(is_expensive);
  }
  virtual void SetBuildType(bool is_official) {
    base_fetcher_->SetBuildType(is_official);
  }
  virtual void SetProxies(const std::deque<std::string>& proxies) {
    base_fetcher_->SetProxies(proxies);
  }

  inline virtual size_t GetBytesDownloaded() {
    return base_fetcher_->GetBytesDownloaded();
  }

 private:
  // A range object defining the offset and length of a download chunk.  Zero
  // length indicates an unspecified end offset (note that it is impossible to
  // request a zero-length range in HTTP).
  class Range {
   public:
    Range(off_t offset, size_t length) : offset_(offset), length_(length) {}
    Range(off_t offset) : offset_(offset), length_(0) {}

    inline off_t offset() const { return offset_; }
    inline size_t length() const { return length_; }

    inline bool HasLength() const { return (length_ > 0); }

    std::string ToString() const;

   private:
    off_t offset_;
    size_t length_;
  };

  typedef std::vector<Range> RangesVect;
  
  // State change: Stopped or Downloading -> Downloading
  void StartTransfer();

// State change: Downloading -> Downloading or Pending transfer ended
  virtual void ReceivedBytes(HttpFetcher* fetcher,
                             const char* bytes,
                             int length);

  // State change: Pending transfer ended -> Stopped
  void TransferEnded(HttpFetcher* fetcher, bool successful);
  // These two call TransferEnded():
  virtual void TransferComplete(HttpFetcher* fetcher, bool successful);
  virtual void TransferTerminated(HttpFetcher* fetcher);

  void Reset();

  scoped_ptr<HttpFetcher> base_fetcher_;

  // If true, do not send any more data or TransferComplete to the delegate.
  bool base_fetcher_active_;

  // If true, the next fetcher needs to be started when TransferTerminated is
  // received from the current fetcher.
  bool pending_transfer_ended_;
  
  // True if we are waiting for base fetcher to terminate b/c we are
  // ourselves terminating.
  bool terminating_;

  RangesVect ranges_;

  RangesVect::size_type current_index_;  // index into ranges_
  size_t bytes_received_this_range_;

  DISALLOW_COPY_AND_ASSIGN(MultiRangeHttpFetcher);
};

}  // namespace chromeos_update_engine

#endif  // CHROMEOS_PLATFORM_UPDATE_ENGINE_MULTI_RANGE_HTTP_FETCHER_H__
