// 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

// Fake implementation of dbus interfaces that wraps the godbus
// library github.com/godbus/dbus. This is mainly for unittest.

import godbus "github.com/godbus/dbus"

type ConnFake struct {
	bus_object *BusObjectFake
	// A map from <dest>+<path> to fake bus object.
	objects map[string]*BusObjectFake
	// Holds the channel that sends received dbus signals.
	signal_channel chan<- *godbus.Signal
}

type CallFake struct {
	// Holds the return values once the call is done.
	rets []interface{}
	err  error
}

type BusObjectFake struct {
	// A map from method name to call function.
	calls map[string]CallMethod
}

// A generic type to represents any call functions.
type CallMethod func(args ...interface{}) ([]interface{}, error)

// NewFakeConn returns a new empty fake connection.
func NewFakeConn() *ConnFake {
	return &ConnFake{
		nil,
		make(map[string]*BusObjectFake),
		nil,
	}
}

func (conn *ConnFake) BusObject() BusObject {
	return conn.bus_object
}

func (conn *ConnFake) Close() error {
	return nil
}

func (conn *ConnFake) Object(dest string, path string) BusObject {
	return conn.objects[dest+path]
}

func (conn *ConnFake) SetBusObject(obj *BusObjectFake) {
	conn.bus_object = obj
}

func (conn *ConnFake) SetObject(dest string, path string, obj *BusObjectFake) {
	conn.objects[dest+path] = obj
}

func (conn *ConnFake) Signal(ch chan<- *godbus.Signal) {
	conn.signal_channel = ch
}

// NewFakeBusObject returns a new empty fake object.
func NewFakeBusObject() *BusObjectFake {
	return &BusObjectFake{
		make(map[string]CallMethod),
	}
}

func (obj *BusObjectFake) Call(method string, flags godbus.Flags, args ...interface{}) Call {
	rets, err := obj.calls[method](args...)
	return &CallFake{rets, err}
}

func (obj *BusObjectFake) SetCall(method string, call CallMethod) {
	obj.calls[method] = call
}

func (call *CallFake) Store(retvalues ...interface{}) error {
	if call.err != nil {
		return call.err
	}
	return godbus.Store(call.rets, retvalues...)
}

func (call *CallFake) GetError() error {
	return call.err
}
