// Copyright (c) 2012 The Chromium 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 PPAPI_PROXY_SERIALIZED_VAR_H_
#define PPAPI_PROXY_SERIALIZED_VAR_H_

#include <string>
#include <vector>

#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/shared_memory.h"
#include "ppapi/c/pp_instance.h"
#include "ppapi/c/pp_var.h"
#include "ppapi/proxy/ppapi_proxy_export.h"
#include "ppapi/proxy/raw_var_data.h"
#include "ppapi/proxy/serialized_handle.h"
#include "ppapi/proxy/serialized_structs.h"
#include "ppapi/proxy/var_serialization_rules.h"

class PickleIterator;

namespace IPC {
class Message;
}

namespace ppapi {
namespace proxy {

class Dispatcher;
class VarSerializationRules;

// This class encapsulates a var so that we can serialize and deserialize it.
// The problem is that for strings, serialization and deserialization requires
// knowledge from outside about how to get at or create a string. So this
// object groups the var with a dispatcher so that string values can be set or
// gotten.
//
// Declare IPC messages as using this type, but don't use it directly (it has
// no useful public methods). Instead, instantiate one of the helper classes
// below which are conveniently named for each use case to prevent screwups.
//
// Design background
// -----------------
// This is sadly super complicated. The IPC system needs a consistent type to
// use for sending and receiving vars (this is a SerializedVar). But there are
// different combinations of reference counting for sending and receiving
// objects and for dealing with strings
//
// This makes SerializedVar complicated and easy to mess up. To make it
// reasonable to use, all functions are protected and there are use-specific
// classes that each encapsulate exactly one type of use in a way that typically
// won't compile if you do the wrong thing.
//
// The IPC system is designed to pass things around and will make copies in
// some cases, so our system must be designed so that this stuff will work.
// This is challenging when the SerializedVar must do some cleanup after the
// message is sent. To work around this, we create an inner class using a
// linked_ptr so all copies of a SerializedVar can share and we can guarantee
// that the actual data will get cleaned up on shutdown.
//
// Constness
// ---------
// SerializedVar basically doesn't support const. Everything is mutable and
// most functions are declared const. This unfortunateness is because of the
// way the IPC system works. When deserializing, it will have a const
// SerializedVar in a Tuple and this will be given to the function. We kind of
// want to modify that to convert strings and do refcounting.
//
// The helper classes used for accessing the SerializedVar have more reasonable
// behavior and will enforce that you don't do stupid things.
class PPAPI_PROXY_EXPORT SerializedVar {
 public:
  SerializedVar();
  ~SerializedVar();

  // Backend implementation for IPC::ParamTraits<SerializedVar>.
  void WriteToMessage(IPC::Message* m) const {
    inner_->WriteToMessage(m);
  }
  // If ReadFromMessage has been called, WriteDataToMessage will write the var
  // that has been read from ReadFromMessage back to a message. This is used
  // when converting handles for use in NaCl.
  void WriteDataToMessage(IPC::Message* m,
                          const HandleWriter& handle_writer) const {
    inner_->WriteDataToMessage(m, handle_writer);
  }
  bool ReadFromMessage(const IPC::Message* m, PickleIterator* iter) {
    return inner_->ReadFromMessage(m, iter);
  }

  bool is_valid_var() const {
    return inner_->is_valid_var();
  }

  // Returns the shared memory handles associated with this SerializedVar.
  std::vector<SerializedHandle*> GetHandles() const {
    return inner_->GetHandles();
  }

 protected:
  friend class SerializedVarReceiveInput;
  friend class SerializedVarReturnValue;
  friend class SerializedVarOutParam;
  friend class SerializedVarSendInput;
  friend class SerializedVarSendInputShmem;
  friend class SerializedVarTestConstructor;
  friend class SerializedVarVectorReceiveInput;

  class PPAPI_PROXY_EXPORT Inner : public base::RefCounted<Inner> {
   public:
    Inner();
    Inner(VarSerializationRules* serialization_rules);
    ~Inner();

    VarSerializationRules* serialization_rules() {
      return serialization_rules_.get();
    }
    void set_serialization_rules(VarSerializationRules* serialization_rules) {
      serialization_rules_ = serialization_rules;
    }

    bool is_valid_var() const {
      return is_valid_var_;
    }

    std::vector<SerializedHandle*> GetHandles() {
      return (raw_var_data_ ? raw_var_data_->GetHandles() :
          std::vector<SerializedHandle*>());
    }

    // See outer class's declarations above.
    PP_Var GetVar();
    void SetVar(PP_Var var);
    void SetInstance(PP_Instance instance);

    // For the SerializedVarTestConstructor, this writes the Var value as if
    // it was just received off the wire, without any serialization rules.
    void ForceSetVarValueForTest(PP_Var value);

    void WriteToMessage(IPC::Message* m) const;
    void WriteDataToMessage(IPC::Message* m,
                            const HandleWriter& handle_writer) const;
    bool ReadFromMessage(const IPC::Message* m, PickleIterator* iter);

    // Sets the cleanup mode. See the CleanupMode enum below.
    void SetCleanupModeToEndSendPassRef();
    void SetCleanupModeToEndReceiveCallerOwned();

   private:
    enum CleanupMode {
      // The serialized var won't do anything special in the destructor
      // (default).
      CLEANUP_NONE,

      // The serialized var will call EndSendPassRef in the destructor.
      END_SEND_PASS_REF,

      // The serialized var will call EndReceiveCallerOwned in the destructor.
      END_RECEIVE_CALLER_OWNED
    };

    // Rules for serializing and deserializing vars for this process type.
    // This may be NULL, but must be set before trying to serialize to IPC when
    // sending, or before converting back to a PP_Var when receiving.
    scoped_refptr<VarSerializationRules> serialization_rules_;

    // If this is set to VARTYPE_STRING and the 'value.id' is 0, then the
    // string_from_ipc_ holds the string. This means that the caller hasn't
    // called Deserialize with a valid Dispatcher yet, which is how we can
    // convert the serialized string value to a PP_Var string ID.
    //
    // This var may not be complete until the serialization rules are set when
    // reading from IPC since we'll need that to convert the string_value to
    // a string ID. Before this, the as_id will be 0 for VARTYPE_STRING.
    PP_Var var_;

    PP_Instance instance_;

    CleanupMode cleanup_mode_;

    // If the var is not properly serialized, this will be false.
    bool is_valid_var_;

#ifndef NDEBUG
    // When being sent or received over IPC, we should only be serialized or
    // deserialized once. These flags help us assert this is true.
    mutable bool has_been_serialized_;
    mutable bool has_been_deserialized_;
#endif

    // ReadFromMessage() may be called on the I/O thread, e.g., when reading the
    // reply to a sync message. We cannot use the var tracker on the I/O thread,
    // which means we cannot create some types of PP_Var
    // (e.g. PP_VARTYPE_STRING). The data is stored in |raw_var_data_| and the
    // PP_Var is constructed when |GetVar()| is called.
    scoped_ptr<RawVarDataGraph> raw_var_data_;

    DISALLOW_COPY_AND_ASSIGN(Inner);
  };

  SerializedVar(VarSerializationRules* serialization_rules);

  mutable scoped_refptr<Inner> inner_;
};

// Helpers for message sending side --------------------------------------------

// For sending a value to the remote side.
//
// Example for API:
//   void MyFunction(PP_Var)
// IPC message:
//   IPC_MESSAGE_ROUTED1(MyFunction, SerializedVar);
// Sender would be:
//   void MyFunctionProxy(PP_Var param) {
//     Send(new MyFunctionMsg(SerializedVarSendInput(dispatcher, param));
//   }
class PPAPI_PROXY_EXPORT SerializedVarSendInput : public SerializedVar {
 public:
  SerializedVarSendInput(Dispatcher* dispatcher, const PP_Var& var);

  // Helper function for serializing a vector of input vars for serialization.
  static void ConvertVector(Dispatcher* dispatcher,
                            const PP_Var* input,
                            size_t input_count,
                            std::vector<SerializedVar>* output);

 private:
  // Disallow the empty constructor, but keep the default copy constructor
  // which is required to send the object to the IPC system.
  SerializedVarSendInput();
};

// Specialization for optionally sending over shared memory.
class PPAPI_PROXY_EXPORT SerializedVarSendInputShmem : public SerializedVar {
 public:
  SerializedVarSendInputShmem(Dispatcher* dispatcher, const PP_Var& var,
                              const PP_Instance& instance);

 private:
  // Disallow the empty constructor, but keep the default copy constructor
  // which is required to send the object to the IPC system.
  SerializedVarSendInputShmem();
};


// For the calling side of a function returning a var. The sending side uses
// SerializedVarReturnValue.
//
// Example for API:
//   PP_Var MyFunction()
// IPC message:
//   IPC_SYNC_MESSAGE_ROUTED0_1(MyFunction, SerializedVar);
// Message handler would be:
//   PP_Var MyFunctionProxy() {
//     ReceiveSerializedVarReturnValue result;
//     Send(new MyFunctionMsg(&result));
//     return result.Return(dispatcher());
//   }
//
// TODO(yzshen): Move the dispatcher parameter to the constructor and store a
// VarSerializationRules reference instead, in case the dispatcher is destroyed
// while waiting for reply to the sync message.
class PPAPI_PROXY_EXPORT ReceiveSerializedVarReturnValue
    : public SerializedVar {
 public:
  // Note that we can't set the dispatcher in the constructor because the
  // data will be overridden when the return value is set. This constructor is
  // normally used in the pattern above (operator= will be implicitly invoked
  // when the sync message writes the output values).
  ReceiveSerializedVarReturnValue();

  // This constructor can be used when deserializing manually. This is useful
  // when you're getting strings "returned" via a struct and need to manually
  // get the PP_Vars out. In this case just do:
  //   ReceiveSerializedVarReturnValue(serialized).Return(dispatcher);
  explicit ReceiveSerializedVarReturnValue(const SerializedVar& serialized);

  PP_Var Return(Dispatcher* dispatcher);

 private:
  DISALLOW_COPY_AND_ASSIGN(ReceiveSerializedVarReturnValue);
};

// Example for API:
//   "void MyFunction(PP_Var* exception);"
// IPC message:
//   IPC_SYNC_MESSAGE_ROUTED0_1(MyFunction, SerializedVar);
// Message handler would be:
//   void OnMsgMyFunction(PP_Var* exception) {
//     ReceiveSerializedException se(dispatcher(), exception)
//     Send(new PpapiHostMsg_Foo(&se));
//   }
class PPAPI_PROXY_EXPORT ReceiveSerializedException : public SerializedVar {
 public:
  ReceiveSerializedException(Dispatcher* dispatcher, PP_Var* exception);
  ~ReceiveSerializedException();

  // Returns true if the exception passed in the constructor is set. Check
  // this before actually issuing the IPC.
  bool IsThrown() const;

 private:
  // The input/output exception we're wrapping. May be NULL.
  PP_Var* exception_;

  DISALLOW_IMPLICIT_CONSTRUCTORS(ReceiveSerializedException);
};

// Helper class for when we're returning a vector of Vars. When it goes out
// of scope it will automatically convert the vector filled by the IPC layer
// into the array specified by the constructor params.
//
// Example for API:
//   "void MyFunction(uint32_t* count, PP_Var** vars);"
// IPC message:
//   IPC_SYNC_MESSAGE_ROUTED0_1(MyFunction, std::vector<SerializedVar>);
// Proxy function:
//   void MyFunction(uint32_t* count, PP_Var** vars) {
//     ReceiveSerializedVarVectorOutParam vect(dispatcher, count, vars);
//     Send(new MyMsg(vect.OutParam()));
//   }
class PPAPI_PROXY_EXPORT ReceiveSerializedVarVectorOutParam {
 public:
  ReceiveSerializedVarVectorOutParam(Dispatcher* dispatcher,
                                     uint32_t* output_count,
                                     PP_Var** output);
  ~ReceiveSerializedVarVectorOutParam();

  std::vector<SerializedVar>* OutParam();

 private:
  Dispatcher* dispatcher_;
  uint32_t* output_count_;
  PP_Var** output_;

  std::vector<SerializedVar> vector_;

  DISALLOW_IMPLICIT_CONSTRUCTORS(ReceiveSerializedVarVectorOutParam);
};

// Helpers for message receiving side ------------------------------------------

// For receiving a value from the remote side.
//
// Example for API:
//   void MyFunction(PP_Var)
// IPC message:
//   IPC_MESSAGE_ROUTED1(MyFunction, SerializedVar);
// Message handler would be:
//   void OnMsgMyFunction(SerializedVarReceiveInput param) {
//     MyFunction(param.Get());
//   }
class PPAPI_PROXY_EXPORT SerializedVarReceiveInput {
 public:
  // We rely on the implicit constructor here since the IPC layer will call
  // us with a SerializedVar. Pass this object by value, the copy constructor
  // will pass along the pointer (as cheap as passing a pointer arg).
  SerializedVarReceiveInput(const SerializedVar& serialized);
  ~SerializedVarReceiveInput();

  PP_Var Get(Dispatcher* dispatcher);
  PP_Var GetForInstance(Dispatcher* dispatcher, PP_Instance instance);
  bool is_valid_var() { return serialized_.is_valid_var(); }

 private:
  const SerializedVar& serialized_;
};

// For receiving an input vector of vars from the remote side.
//
// Example:
//   OnMsgMyFunction(SerializedVarVectorReceiveInput vector) {
//     uint32_t size;
//     PP_Var* array = vector.Get(dispatcher, &size);
//     MyFunction(size, array);
//   }
class PPAPI_PROXY_EXPORT SerializedVarVectorReceiveInput {
 public:
  SerializedVarVectorReceiveInput(const std::vector<SerializedVar>& serialized);
  ~SerializedVarVectorReceiveInput();

  // Only call Get() once. It will return a pointer to the converted array and
  // place the array size in the out param. Will return NULL when the array is
  // empty.
  PP_Var* Get(Dispatcher* dispatcher, uint32_t* array_size);

 private:
  const std::vector<SerializedVar>& serialized_;

  // Filled by Get().
  std::vector<PP_Var> deserialized_;
};

// For the receiving side of a function returning a var. The calling side uses
// ReceiveSerializedVarReturnValue.
//
// Example for API:
//   PP_Var MyFunction()
// IPC message:
//   IPC_SYNC_MESSAGE_ROUTED0_1(MyFunction, SerializedVar);
// Message handler would be:
//   void OnMsgMyFunction(SerializedVarReturnValue result) {
//     result.Return(dispatcher(), MyFunction());
//   }
class PPAPI_PROXY_EXPORT SerializedVarReturnValue {
 public:
  // We rely on the implicit constructor here since the IPC layer will call
  // us with a SerializedVar*. Pass this object by value, the copy constructor
  // will pass along the pointer (as cheap as passing a pointer arg).
  SerializedVarReturnValue(SerializedVar* serialized);

  void Return(Dispatcher* dispatcher, const PP_Var& var);

  // Helper function for code that doesn't use the pattern above, but gets
  // a return value from the remote side via a struct. You can pass in the
  // SerializedVar and a PP_Var will be created with return value semantics.
  static SerializedVar Convert(Dispatcher* dispatcher, const PP_Var& var);

 private:
  SerializedVar* serialized_;
};

// For writing an out param to the remote side.
//
// Example for API:
//   "void MyFunction(PP_Var* out);"
// IPC message:
//   IPC_SYNC_MESSAGE_ROUTED0_1(MyFunction, SerializedVar);
// Message handler would be:
//   void OnMsgMyFunction(SerializedVarOutParam out_param) {
//     MyFunction(out_param.OutParam(dispatcher()));
//   }
class PPAPI_PROXY_EXPORT SerializedVarOutParam {
 public:
  // We rely on the implicit constructor here since the IPC layer will call
  // us with a SerializedVar*. Pass this object by value, the copy constructor
  // will pass along the pointer (as cheap as passing a pointer arg).
  SerializedVarOutParam(SerializedVar* serialized);
  ~SerializedVarOutParam();

  // Call this function only once. The caller should write its result to the
  // returned var pointer before this class goes out of scope. The var's
  // initial value will be VARTYPE_UNDEFINED.
  PP_Var* OutParam(Dispatcher* dispatcher);

 private:
  SerializedVar* serialized_;

  // This is the value actually written by the code and returned by OutParam.
  // We'll write this into serialized_ in our destructor.
  PP_Var writable_var_;

  Dispatcher* dispatcher_;
};

// For returning an array of PP_Vars to the other side and transferring
// ownership.
//
class PPAPI_PROXY_EXPORT SerializedVarVectorOutParam {
 public:
  SerializedVarVectorOutParam(std::vector<SerializedVar>* serialized);
  ~SerializedVarVectorOutParam();

  uint32_t* CountOutParam() { return &count_; }
  PP_Var** ArrayOutParam(Dispatcher* dispatcher);

 private:
  Dispatcher* dispatcher_;
  std::vector<SerializedVar>* serialized_;

  uint32_t count_;
  PP_Var* array_;
};

// For tests that just want to construct a SerializedVar for giving it to one
// of the other classes. This emulates a SerializedVar just received over the
// wire from another process.
class PPAPI_PROXY_EXPORT SerializedVarTestConstructor : public SerializedVar {
 public:
  // For POD-types and objects.
  explicit SerializedVarTestConstructor(const PP_Var& pod_var);

  // For strings.
  explicit SerializedVarTestConstructor(const std::string& str);
};

// For tests that want to read what's in a SerializedVar.
class PPAPI_PROXY_EXPORT SerializedVarTestReader : public SerializedVar {
 public:
  explicit SerializedVarTestReader(const SerializedVar& var);

  PP_Var GetVar() const { return inner_->GetVar(); }
};

}  // namespace proxy
}  // namespace ppapi

#endif  // PPAPI_PROXY_SERIALIZED_VAR_H_
