//
// 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.
//

#ifndef UPDATE_ENGINE_PAYLOAD_PROPERTIES_REQUEST_ACTION_H_
#define UPDATE_ENGINE_PAYLOAD_PROPERTIES_REQUEST_ACTION_H_

#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>

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

#include <gtest/gtest_prod.h>  // for FRIEND_TEST

#include <brillo/secure_blob.h>
#include <curl/curl.h>

#include "update_engine/common/action.h"
#include "update_engine/common/http_fetcher.h"
#include "update_engine/payload_properties.h"
#include "update_engine/system_state.h"

// The Payload Properties action downloads properties header and outputs
// properties on the output ActionPipe.

namespace chromeos_update_engine {

class PayloadPropertiesRequestAction;

template<>
class ActionTraits<PayloadPropertiesRequestAction> {
 public:
  // Takes parameters on the input pipe.
  typedef NoneType InputObjectType;
  typedef PayloadProperties OutputObjectType;
};


class PayloadPropertiesRequestAction : public Action<PayloadPropertiesRequestAction>,
                           public HttpFetcherDelegate {
 public:
  PayloadPropertiesRequestAction(SystemState* system_state,
                     PayloadProperties *properties,
                     HttpFetcher *http_fetcher);
  ~PayloadPropertiesRequestAction() override;
  typedef ActionTraits<PayloadPropertiesRequestAction>::InputObjectType InputObjectType;
  typedef ActionTraits<PayloadPropertiesRequestAction>::OutputObjectType OutputObjectType;
  void PerformAction() override;
  void TerminateProcessing() override;
  void ActionCompleted(ErrorCode code) override;

  int GetHTTPResponseCode() { return http_fetcher_->http_response_code(); }

  // Debugging/logging
  static std::string StaticType() { return "PayloadPropertiesRequestAction"; }
  std::string Type() const override { return StaticType(); }

  // Delegate methods (see http_fetcher.h)
  void ReceivedBytes(HttpFetcher *fetcher,
                     const void* bytes, size_t length) override;

  void TransferComplete(HttpFetcher *fetcher, bool successful) override;

private:
  // Global system context.
  SystemState* system_state_;

  PayloadProperties * properties_;

  // pointer to the HttpFetcher that does the http work
  std::unique_ptr<HttpFetcher> http_fetcher_;

  // Stores the response from the omaha server
  brillo::Blob response_buffer_;

  DISALLOW_COPY_AND_ASSIGN(PayloadPropertiesRequestAction);
};

}  // namespace chromeos_update_engine

#endif  // UPDATE_ENGINE_PAYLOAD_PROPERTIES_REQUEST_ACTION_H_
