// Copyright (c) 2013 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 REMOTING_HOST_WIN_CHROMOTING_MODULE_H_
#define REMOTING_HOST_WIN_CHROMOTING_MODULE_H_

#include <atlbase.h>
#include <atlcom.h>
#include <atlctl.h>

#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
#include "base/win/scoped_com_initializer.h"

// chromoting_lib.h contains MIDL-generated declarations.
#include "remoting/host/chromoting_lib.h"

namespace base {
namespace win {
class ScopedCOMInitializer;
}  // namespace win
}  // namespace base

namespace remoting {

class AutoThreadTaskRunner;

// A custom version of |CAtlModuleT<>| that registers only those classes which
// registration entries are passed to the constructor. |ChromotingModule| runs
// |MessageLoop| allowing Chromium code to post tasks to it. Unlike
// |CAtlExeModuleT<>|, |ChromotingModule| shuts itself down immediately once
// the last COM object is released.
class ChromotingModule : public ATL::CAtlModuleT<ChromotingModule> {
 public:
  // Initializes the module. |classes| and |classes_end| must outlive |this|.
  ChromotingModule(ATL::_ATL_OBJMAP_ENTRY* classes,
                   ATL::_ATL_OBJMAP_ENTRY* classes_end);
  virtual ~ChromotingModule();

  // Returns the task runner used by the module. Returns NULL if the task runner
  // hasn't been registered yet or if the server is shutting down.
  static scoped_refptr<AutoThreadTaskRunner> task_runner();

  // Registers COM classes and runs the main message loop until there are
  // components using it.
  bool Run();

  // ATL::CAtlModuleT<> overrides
  virtual LONG Unlock() OVERRIDE;

  DECLARE_LIBID(LIBID_ChromotingLib)

 private:
  // Registers/unregisters class objects from |classes_| - |classes_end_|.
  HRESULT RegisterClassObjects(DWORD class_context, DWORD flags);
  HRESULT RevokeClassObjects();

  // Used to initialize COM library.
  base::win::ScopedCOMInitializer com_initializer_;

  // Point to the vector of classes registered by this module.
  ATL::_ATL_OBJMAP_ENTRY* classes_;
  ATL::_ATL_OBJMAP_ENTRY* classes_end_;

  DISALLOW_COPY_AND_ASSIGN(ChromotingModule);
};

} // namespace remoting

#endif  // REMOTING_HOST_WIN_CHROMOTING_MODULE_H_
