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

// Unit tests for the UpdateEngineClient implementation.
package dbus

import (
	"errors"
	"github.com/golang/protobuf/proto"
	"policy_manager/policymanagerproto"
	"reflect"
	"testing"

	godbus "github.com/godbus/dbus"
)

func newFakeUpdateEngineClient(fakeConn Conn) UpdateEngineClient {
	return &updateEngineClientImpl{fakeConn}
}

// TestSetChannel tests SetChannel calls dbus method as expected.
func TestSetChannel(t *testing.T) {
	tests := []struct {
		name          string
		targetChannel string
		expectError   bool
	}{
		{
			"NormalCase",
			"foo-channel",
			false,
		},
		{
			"ErrorCase",
			"bar-channel",
			true,
		},
	}

	for _, test := range tests {
		// Mock dbus connection and object.
		fakeConn := NewFakeConn()
		fakeObj := NewFakeBusObject()
		fakeCall := func(args ...interface{}) ([]interface{}, error) {
			if !test.expectError {
				// Check arguments.
				if len(args) != 2 || args[0] != test.targetChannel || args[1] != false {
					return nil, errors.New("Check args failed.")
				}
				return nil, nil
			} else {
				return nil, errors.New("Expected error.")
			}
		}
		fakeConn.SetObject(updateEngineObjectName, updateEngineObjectPath, fakeObj)
		fakeObj.SetCall(setChannelMethod, fakeCall)

		ueClient := newFakeUpdateEngineClient(fakeConn)
		err := ueClient.SetChannel(test.targetChannel)

		if err != nil && !test.expectError {
			t.Errorf("Test %s got unexpected error: %v", test.name, err)
		} else if err == nil && test.expectError {
			t.Errorf("Test %s didn't get expected error", test.name)
		}
	}
}

// TestAttemptUpdate tests AttemptUpdate calls dbus method as expected.
func TestAttemptUpdate(t *testing.T) {
	tests := []struct {
		name        string
		expectError bool
	}{
		{
			"NormalCase",
			false,
		},
		{
			"ErrorCase",
			true,
		},
	}

	for _, test := range tests {
		// Mock dbus connection and object.
		fakeConn := NewFakeConn()
		fakeObj := NewFakeBusObject()
		fakeCall := func(args ...interface{}) ([]interface{}, error) {
			if !test.expectError {
				// Check arguments.
				if len(args) != 2 || args[0] != "" || args[1] != "" {
					return nil, errors.New("Check args failed.")
				}
				return nil, nil
			} else {
				return nil, errors.New("Expected error.")
			}
		}
		fakeConn.SetObject(updateEngineObjectName, updateEngineObjectPath, fakeObj)
		fakeObj.SetCall(attemptUpdateMethod, fakeCall)

		ueClient := newFakeUpdateEngineClient(fakeConn)
		err := ueClient.AttemptUpdate()

		if err != nil && !test.expectError {
			t.Errorf("Test %s got unexpected error %v", test.name, err)
		} else if err == nil && test.expectError {
			t.Errorf("Test %s didn't get expected error", test.name)
		}
	}
}

// TestGetStatus tests GetStatus returns correct values.
func TestGetStatus(t *testing.T) {
	rebootStatus := policymanagerproto.Operation_UPDATED_NEED_REBOOT
	tests := []struct {
		name           string
		expectedReturn *policymanagerproto.StatusResult
		expectError    bool
	}{
		{
			"NormalCase",
			&policymanagerproto.StatusResult{
				NewVersion:      proto.String("16550.0.0"),
				UpdateStatus:    &rebootStatus,
				LastCheckedTime: proto.Int64(1433971203),
			},
			false,
		},
		{
			"ErrorCase",
			&policymanagerproto.StatusResult{
				NewVersion:      proto.String("16550.0.0"),
				UpdateStatus:    nil,
				LastCheckedTime: proto.Int64(1433971203),
			},
			true,
		},
	}

	for _, test := range tests {
		// Mock dbus connection and object.
		fakeConn := NewFakeConn()
		fakeObj := NewFakeBusObject()
		updateStatusBytes, err := proto.Marshal(test.expectedReturn)
		if err != nil {
			t.Errorf("Failed to marshal UpdateStatusBytes %v", updateStatusBytes)
		}
		fakeCall := func(args ...interface{}) ([]interface{}, error) {
			if !test.expectError {
				return []interface{}{
					updateStatusBytes,
				}, nil
			} else {
				return nil, errors.New("Expected error.")
			}
		}
		fakeConn.SetObject(updateEngineObjectName, updateEngineObjectPath, fakeObj)
		fakeObj.SetCall(getStatusAdvancedMethod, fakeCall)

		ueClient := newFakeUpdateEngineClient(fakeConn)
		ret, err := ueClient.GetStatus()

		if err == nil {
			if test.expectError {
				t.Errorf("Test %s didn't get expected error", test.name)
			} else if !proto.Equal(test.expectedReturn, ret) {
				t.Errorf("Test %s got unexpected return %v, want %v", test.name, ret, test.expectedReturn)
			}
		} else if !test.expectError {
			t.Errorf("Test %s got unexpected error %v", test.name, err)
		}
	}
}

// TestSubscribeStatusUpdate tests SubscribeStatusUpdate returns working channel
func TestSubscribeStatusUpdate(t *testing.T) {
	tests := []struct {
		name           string
		expectedReturn UEGetStatusResponse
		expectError    bool
	}{
		{
			"NormalCase",
			UEGetStatusResponse{
				1433971203,
				0.000000,
				"UPDATE_STATUS_UPDATED_NEED_REBOOT",
				"7150.0.0",
				66542575,
			},
			false,
		},
		{
			"ErrorCase",
			UEGetStatusResponse{},
			true,
		},
	}

	for _, test := range tests {
		// Mock dbus connection and object.
		fakeConn := NewFakeConn()
		fakeObj := NewFakeBusObject()
		fakeCall := func(args ...interface{}) ([]interface{}, error) {
			if test.expectError {
				return nil, errors.New("Expected error.")
			} else {
				return nil, nil
			}
		}
		fakeConn.SetBusObject(fakeObj)
		fakeObj.SetCall(dBusAddMatchMethod, fakeCall)

		ueClient := newFakeUpdateEngineClient(fakeConn)
		ch, err := ueClient.SubscribeStatusUpdate()

		if err == nil {
			if test.expectError {
				t.Errorf("Test %s didn't get expected error", test.name)
			} else {
				fakeConn.signal_channel <- &godbus.Signal{
					Body: []interface{}{
						test.expectedReturn.LastCheckedTime,
						test.expectedReturn.Progress,
						test.expectedReturn.UpdateStatus,
						test.expectedReturn.NewVersion,
						test.expectedReturn.NewSize,
					},
				}
				ret := <-ch
				if !reflect.DeepEqual(test.expectedReturn, ret) {
					t.Errorf("Test %s got unexpected return %v, want %v", test.name, ret, test.expectedReturn)
				}
			}
		} else if !test.expectError {
			t.Errorf("Test %s got unexpected error %v", test.name, err)
		}
	}
}
