// Copyright 2021 Google LLC
//
// 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.

package dbus

// Implementation of dbus interfaces that wraps the godbus
// library github.com/godbus/dbus.

import godbus "github.com/godbus/dbus"

type connImpl struct {
	conn *godbus.Conn
}

type callImpl struct {
	call *godbus.Call
}

type busObjectImpl struct {
	busObject godbus.BusObject
}

func (conn *connImpl) BusObject() BusObject {
	return &busObjectImpl{conn.conn.BusObject()}
}

func (conn *connImpl) Close() error {
	return conn.conn.Close()
}

func (conn *connImpl) Object(dest string, path string) BusObject {
	return &busObjectImpl{conn.conn.Object(dest, godbus.ObjectPath(path))}
}

func (conn *connImpl) Signal(ch chan<- *godbus.Signal) {
	conn.conn.Signal(ch)
}

// SystemBus returns a shared connection to the system bus, connecting to it if
// not already done.
func SystemBus() (Conn, error) {
	conn, err := godbus.SystemBus()
	if err != nil {
		return nil, err
	}
	return &connImpl{conn}, nil
}

// SystemBusPrivate returns a new private connection to the system bus.
func SystemBusPrivate() (Conn, error) {
	conn, err := godbus.SystemBusPrivate()
	if err != nil {
		return nil, err
	}
	if err = conn.Auth(nil); err != nil {
		conn.Close()
		return nil, err
	}
	if err = conn.Hello(); err != nil {
		conn.Close()
		return nil, err
	}
	return &connImpl{conn}, nil
}

func (call *callImpl) Store(retvalues ...interface{}) error {
	return call.call.Store(retvalues...)
}

func (call *callImpl) GetError() error {
	return call.call.Err
}

func (obj *busObjectImpl) Call(method string, flags godbus.Flags, args ...interface{}) Call {
	return &callImpl{obj.busObject.Call(method, flags, args...)}
}
