//
// Copyright (C) 2014 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.
//

#include "apmanager/service.h"

#include <signal.h>

#include <base/bind.h>
#include <base/strings/stringprintf.h>
#include <brillo/errors/error.h>

#if !defined(__ANDROID__)
#include <chromeos/dbus/service_constants.h>
#else
#include <dbus/apmanager/dbus-constants.h>
#endif  // __ANDROID__

#if defined(__BRILLO__)
#include "apmanager/event_dispatcher.h"
#endif  // __BRILLO__

#include "apmanager/control_interface.h"
#include "apmanager/manager.h"

using std::string;

namespace apmanager {

// static.
#if !defined(__ANDROID__)
const char Service::kHostapdPath[] = "/usr/sbin/hostapd";
const char Service::kHostapdConfigPathFormat[] =
    "/run/apmanager/hostapd/hostapd-%d.conf";
const char Service::kHostapdControlInterfacePath[] =
    "/run/apmanager/hostapd/ctrl_iface";
#else
const char Service::kHostapdPath[] = "/system/bin/hostapd";
const char Service::kHostapdConfigPathFormat[] =
    "/data/misc/apmanager/hostapd/hostapd-%d.conf";
const char Service::kHostapdControlInterfacePath[] =
    "/data/misc/apmanager/hostapd/ctrl_iface";
#endif  // __ANDROID__

#if defined(__BRILLO__)
const int Service::kAPInterfaceCheckIntervalMilliseconds = 200;
const int Service::kAPInterfaceCheckMaxAttempts = 5;
#endif  // __BRILLO__

const int Service::kTerminationTimeoutSeconds = 2;

// static. Service state definitions.
const char Service::kStateIdle[] = "Idle";
const char Service::kStateStarting[] = "Starting";
const char Service::kStateStarted[] = "Started";
const char Service::kStateFailed[] = "Failed";

Service::Service(Manager* manager, int service_identifier)
    : manager_(manager),
      identifier_(service_identifier),
      config_(new Config(manager, service_identifier)),
      adaptor_(manager->control_interface()->CreateServiceAdaptor(this)),
      dhcp_server_factory_(DHCPServerFactory::GetInstance()),
      file_writer_(FileWriter::GetInstance()),
      process_factory_(ProcessFactory::GetInstance()) {
  adaptor_->SetConfig(config_.get());
  adaptor_->SetState(kStateIdle);
  // TODO(zqiu): come up with better server address management. This is good
  // enough for now.
  config_->SetServerAddressIndex(identifier_ & 0xFF);

#if defined(__BRILLO__)
  event_dispatcher_ = EventDispatcher::GetInstance();
  start_in_progress_ = false;
#endif
}

Service::~Service() {
  // Stop hostapd process if still running.
  if (IsHostapdRunning()) {
    ReleaseResources();
  }
}

bool Service::StartInternal(Error* error) {
  if (IsHostapdRunning()) {
    Error::PopulateAndLog(
        error, Error::kInternalError, "Service already running", FROM_HERE);
    return false;
  }

  // Setup hostapd control interface path.
  config_->set_control_interface(kHostapdControlInterfacePath);

  // Generate hostapd configuration content.
  string config_str;
  if (!config_->GenerateConfigFile(error, &config_str)) {
    return false;
  }

  // Write configuration to a file.
  string config_file_name = base::StringPrintf(kHostapdConfigPathFormat,
                                               identifier_);
  if (!file_writer_->Write(config_file_name, config_str)) {
    Error::PopulateAndLog(error,
                          Error::kInternalError,
                          "Failed to write configuration to a file",
                          FROM_HERE);
    return false;
  }

  // Claim the device needed for this ap service.
  if (!config_->ClaimDevice()) {
    Error::PopulateAndLog(error,
                          Error::kInternalError,
                          "Failed to claim the device for this service",
                          FROM_HERE);
    return false;
  }

  // Start hostapd process.
  if (!StartHostapdProcess(config_file_name)) {
    Error::PopulateAndLog(
        error, Error::kInternalError, "Failed to start hostapd", FROM_HERE);
    // Release the device claimed for this service.
    config_->ReleaseDevice();
    return false;
  }

  // Start DHCP server if in server mode.
  if (config_->GetOperationMode() == kOperationModeServer) {
    dhcp_server_.reset(
        dhcp_server_factory_->CreateDHCPServer(config_->GetServerAddressIndex(),
                                               config_->selected_interface()));
    if (!dhcp_server_->Start()) {
      Error::PopulateAndLog(error,
                            Error::kInternalError,
                            "Failed to start DHCP server",
                            FROM_HERE);
      ReleaseResources();
      return false;
    }
    manager_->RequestDHCPPortAccess(config_->selected_interface());
  }

  // Start monitoring hostapd.
  if (!hostapd_monitor_) {
    hostapd_monitor_.reset(
        new HostapdMonitor(base::Bind(&Service::HostapdEventCallback,
                                      weak_factory_.GetWeakPtr()),
                           config_->control_interface(),
                           config_->selected_interface()));
  }
  hostapd_monitor_->Start();

  // Update service state.
  adaptor_->SetState(kStateStarting);

  return true;
}

void Service::Start(const base::Callback<void(const Error&)>& result_callback) {
  Error error;

#if !defined(__BRILLO__)
  StartInternal(&error);
  result_callback.Run(error);
#else
  if (start_in_progress_) {
    Error::PopulateAndLog(
        &error, Error::kInternalError, "Start already in progress", FROM_HERE);
    result_callback.Run(error);
    return;
  }

  string interface_name;
  if (!manager_->SetupApModeInterface(&interface_name)) {
    Error::PopulateAndLog(&error,
                          Error::kInternalError,
                          "Failed to setup AP mode interface",
                          FROM_HERE);
    result_callback.Run(error);
    return;
  }

  event_dispatcher_->PostDelayedTask(
      base::Bind(&Service::APInterfaceCheckTask,
                 weak_factory_.GetWeakPtr(),
                 interface_name,
                 0,    // Initial check count.
                 result_callback),
      kAPInterfaceCheckIntervalMilliseconds);
#endif
}

bool Service::Stop(Error* error) {
  if (!IsHostapdRunning()) {
    Error::PopulateAndLog(error,
                          Error::kInternalError,
                          "Service is not currently running", FROM_HERE);
    return false;
  }

  ReleaseResources();
  adaptor_->SetState(kStateIdle);
  return true;
}

#if defined(__BRILLO__)
void Service::HandleStartFailure() {
  // Restore station mode interface.
  string station_mode_interface;
  manager_->SetupStationModeInterface(&station_mode_interface);

  // Reset state variables.
  start_in_progress_ = false;
}

void Service::APInterfaceCheckTask(
    const string& interface_name,
    int check_count,
    const base::Callback<void(const Error&)>& result_callback) {
  Error error;

  // Check if the AP interface is enumerated.
  if (manager_->GetDeviceFromInterfaceName(interface_name)) {
    // Explicitly set the interface name to avoid picking other interface.
    config_->SetInterfaceName(interface_name);
    if (!StartInternal(&error)) {
      HandleStartFailure();
    }
    result_callback.Run(error);
    return;
  }

  check_count++;
  if (check_count >= kAPInterfaceCheckMaxAttempts) {
    Error::PopulateAndLog(&error,
                          Error::kInternalError,
                          "Timeout waiting for AP interface to be enumerated",
                          FROM_HERE);
    HandleStartFailure();
    result_callback.Run(error);
    return;
  }

  event_dispatcher_->PostDelayedTask(
      base::Bind(&Service::APInterfaceCheckTask,
                 weak_factory_.GetWeakPtr(),
                 interface_name,
                 check_count,
                 result_callback),
      kAPInterfaceCheckIntervalMilliseconds);
}
#endif  // __BRILLO__

bool Service::IsHostapdRunning() {
  return hostapd_process_ && hostapd_process_->pid() != 0 &&
         brillo::Process::ProcessExists(hostapd_process_->pid());
}

bool Service::StartHostapdProcess(const string& config_file_path) {
  hostapd_process_.reset(process_factory_->CreateProcess());
  hostapd_process_->AddArg(kHostapdPath);
  hostapd_process_->AddArg(config_file_path);
  if (!hostapd_process_->Start()) {
    hostapd_process_.reset();
    return false;
  }
  return true;
}

void Service::StopHostapdProcess() {
  if (!hostapd_process_->Kill(SIGTERM, kTerminationTimeoutSeconds)) {
    hostapd_process_->Kill(SIGKILL, kTerminationTimeoutSeconds);
  }
  hostapd_process_.reset();
}

void Service::ReleaseResources() {
  hostapd_monitor_.reset();
  StopHostapdProcess();
  dhcp_server_.reset();
  manager_->ReleaseDHCPPortAccess(config_->selected_interface());
#if defined(__BRILLO__)
  // Restore station mode interface.
  string station_mode_interface;
  manager_->SetupStationModeInterface(&station_mode_interface);
#endif  // __BRILLO__
  // Only release device after mode switching had completed, to
  // make sure the station mode interface gets enumerated by
  // shill.
  config_->ReleaseDevice();
}

void Service::HostapdEventCallback(HostapdMonitor::Event event,
                                   const std::string& data) {
  switch (event) {
    case HostapdMonitor::kHostapdFailed:
      adaptor_->SetState(kStateFailed);
      break;
    case HostapdMonitor::kHostapdStarted:
      adaptor_->SetState(kStateStarted);
      break;
    case HostapdMonitor::kStationConnected:
      LOG(INFO) << "Station connected: " << data;
      break;
    case HostapdMonitor::kStationDisconnected:
      LOG(INFO) << "Station disconnected: " << data;
      break;
    default:
      LOG(ERROR) << "Unknown event: " << event;
      break;
  }
}

}  // namespace apmanager
