// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main_test

import (
	"fmt"
	"reflect"
	"sort"
	"sync"
	"testing"
)

type tape struct {
	sync.Mutex
	stimuli   []interface{}
	responses []interface{}
}

func (t *tape) Record(call interface{}) interface{} {
	t.Lock()
	defer t.Unlock()
	t.stimuli = append(t.stimuli, call)

	if len(t.responses) < 1 {
		// Returning an error at this point will likely cause the mock
		// device manager to panic trying to cast the response to what
		// it expects.  Panic'ing here at least makes the issue more
		// apparent.
		// TODO(caprita): Don't panic.
		panic(fmt.Errorf("Record(%#v) had no response", call))
	}
	resp := t.responses[0]
	t.responses = t.responses[1:]
	return resp
}

func (t *tape) SetResponses(responses ...interface{}) {
	t.Lock()
	defer t.Unlock()
	t.responses = make([]interface{}, len(responses))
	copy(t.responses, responses)
}

func (t *tape) Rewind() {
	t.Lock()
	defer t.Unlock()
	t.stimuli = make([]interface{}, 0)
	t.responses = make([]interface{}, 0)
}

func (t *tape) Play() []interface{} {
	t.Lock()
	defer t.Unlock()
	resp := make([]interface{}, len(t.stimuli))
	copy(resp, t.stimuli)
	return resp
}

func newTape() *tape {
	t := new(tape)
	t.Rewind()
	return t
}

type tapeMap struct {
	sync.Mutex
	tapes map[string]*tape
}

func newTapeMap() *tapeMap {
	tm := &tapeMap{
		tapes: make(map[string]*tape),
	}
	return tm
}

func (tm *tapeMap) forSuffix(s string) *tape {
	tm.Lock()
	defer tm.Unlock()
	t, ok := tm.tapes[s]
	if !ok {
		t = new(tape)
		tm.tapes[s] = t
	}
	return t
}

func (tm *tapeMap) rewind() {
	tm.Lock()
	defer tm.Unlock()
	for _, t := range tm.tapes {
		t.Rewind()
	}
}

func TestOneTape(t *testing.T) {
	tm := newTapeMap()
	tm.forSuffix("mytape").SetResponses("b", "c")
	if want, got := "b", tm.forSuffix("mytape").Record("bar"); want != got {
		t.Errorf("Expected %v, got %v", want, got)
	}
	if want, got := "c", tm.forSuffix("mytape").Record("baz"); want != got {
		t.Errorf("Expected %v, got %v", want, got)
	}
	if want, got := []interface{}{"bar", "baz"}, tm.forSuffix("mytape").Play(); !reflect.DeepEqual(want, got) {
		t.Errorf("Expected %v, got %v", want, got)
	}
	tm.forSuffix("mytape").Rewind()
	if want, got := []interface{}{}, tm.forSuffix("mytape").Play(); !reflect.DeepEqual(want, got) {
		t.Errorf("Expected %v, got %v", want, got)
	}
}

func TestManyTapes(t *testing.T) {
	tm := newTapeMap()
	tapes := []string{"duct tape", "cassette tape", "watergate tape", "tape worm"}
	for _, tp := range tapes {
		tm.forSuffix(tp).SetResponses(tp + "resp")
	}
	for _, tp := range tapes {
		if want, got := tp+"resp", tm.forSuffix(tp).Record(tp+"stimulus"); want != got {
			t.Errorf("Expected %v, got %v", want, got)
		}
	}
	for _, tp := range tapes {
		if want, got := []interface{}{tp + "stimulus"}, tm.forSuffix(tp).Play(); !reflect.DeepEqual(want, got) {
			t.Errorf("Expected %v, got %v", want, got)
		}
	}
}

func TestTapeParallelism(t *testing.T) {
	tm := newTapeMap()
	var resp []interface{}
	const N = 100
	for i := 0; i < N; i++ {
		resp = append(resp, fmt.Sprintf("resp%010d", i))
	}
	tm.forSuffix("mytape").SetResponses(resp...)
	results := make(chan string, N)
	for i := 0; i < N; i++ {
		go func(index int) {
			results <- tm.forSuffix("mytape").Record(fmt.Sprintf("stimulus%010d", index)).(string)
		}(i)
	}
	var res []string
	for i := 0; i < N; i++ {
		r := <-results
		res = append(res, r)
	}
	sort.Strings(res)
	var expectedRes []string
	for i := 0; i < N; i++ {
		expectedRes = append(expectedRes, fmt.Sprintf("resp%010d", i))
	}
	if want, got := expectedRes, res; !reflect.DeepEqual(want, got) {
		t.Errorf("Expected %v, got %v", want, got)
	}
	var expectedStimuli []string
	for i := 0; i < N; i++ {
		expectedStimuli = append(expectedStimuli, fmt.Sprintf("stimulus%010d", i))
	}
	var gotStimuli []string
	for _, s := range tm.forSuffix("mytape").Play() {
		gotStimuli = append(gotStimuli, s.(string))
	}
	sort.Strings(gotStimuli)
	if want, got := expectedStimuli, gotStimuli; !reflect.DeepEqual(want, got) {
		t.Errorf("Expected %v, got %v", want, got)
	}
}
