// Copyright 2016 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 "binder_interface.h"
#include "iptables.h"

using android::binder::Status;

using std::string;
using std::vector;

namespace firewalld {

BinderInterface::BinderInterface(IpTables* service)
    : service_(service) {}

Status BinderInterface::PunchTcpHole(int32_t port, const string& iface) {
  if (service_->PunchTcpHole(port, iface)) {
    return Status::ok();
  }

  return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
}

Status BinderInterface::PunchUdpHole(int32_t port, const string& iface) {
  if (service_->PunchUdpHole(port, iface)) {
    return Status::ok();
  }

  return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
}

Status BinderInterface::PlugTcpHole(int32_t port, const string& iface) {
  if (service_->PlugTcpHole(port, iface)) {
    return Status::ok();
  }

  return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
}

Status BinderInterface::PlugUdpHole(int32_t port, const string& iface) {
  if (service_->PlugUdpHole(port, iface)) {
    return Status::ok();
  }

  return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
}

Status BinderInterface::RequestVpnSetup(const vector<string>& usernames,
                                        const string& iface) {
  if (service_->RequestVpnSetup(usernames, iface)) {
    return Status::ok();
  }

  return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
}

Status BinderInterface::RemoveVpnSetup(const vector<string>& usernames,
                                       const string& iface) {
  if (service_->RemoveVpnSetup(usernames, iface)) {
    return Status::ok();
  }

  return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
}

}  // namespace firewalld
