// Copyright 2011 Software Freedom Conservancy
// 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 WEBDRIVER_IE_QUITCOMMANDHANDLER_H_
#define WEBDRIVER_IE_QUITCOMMANDHANDLER_H_

#include "../Browser.h"
#include "../IECommandHandler.h"
#include "../IECommandExecutor.h"

namespace webdriver {

class QuitCommandHandler : public IECommandHandler {
 public:
  QuitCommandHandler(void) {
  }

  virtual ~QuitCommandHandler(void) {
  }

 protected:
  void ExecuteInternal(const IECommandExecutor& executor,
                       const LocatorMap& locator_parameters,
                       const ParametersMap& command_parameters,
                       Response* response) {
    std::vector<std::string> managed_browser_handles;
    executor.GetManagedBrowserHandles(&managed_browser_handles);

    std::vector<std::string>::iterator end = managed_browser_handles.end();
    for (std::vector<std::string>::iterator it = managed_browser_handles.begin();
         it != end;
         ++it) {
      BrowserHandle browser_wrapper;
      int status_code = executor.GetManagedBrowser(*it, &browser_wrapper);
      if (status_code == SUCCESS && !browser_wrapper->is_closing()) {
        browser_wrapper->Close();
      }
    }

    // Calling quit will always result in an invalid session.
    IECommandExecutor& mutable_executor = const_cast<IECommandExecutor&>(executor);
    mutable_executor.set_is_valid(false);
    mutable_executor.set_is_quitting(true);
    response->SetSuccessResponse(Json::Value::null);
  }
};

} // namespace webdriver

#endif // WEBDRIVER_IE_QUITCOMMANDHANDLER_H_
