// Copyright 2017 The Fuchsia Authors. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//    * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//    * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//    * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package lib

import (
	"bytes"
	"context"
	"encoding/binary"
	"errors"
	"fmt"
	"log"
	"math"
	"time"

	"github.com/google/gousb"
)

type Info struct {
	Serial string
}

type Config struct {
	Serial *string `json:"serial"`
}

type Report struct {
	Timestamp uint64
	Values    []float64
}

type Zedmon struct {
	ctx    *gousb.Context
	dev    *gousb.Device
	config *gousb.Config
	intf   *gousb.Interface

	inEpNum  int
	outEpNum int

	inEp  *gousb.InEndpoint
	outEp *gousb.OutEndpoint

	readStream       *gousb.ReadStream
	reportingEnabled bool

	fields []*Field
}

func (z *Zedmon) Close() {
	if z.reportingEnabled {
		z.DisableReporting()
	}

	if z.readStream != nil {
		z.readStream.Close()
	}

	if z.intf != nil {
		z.intf.Close()
	}

	if z.config != nil {
		z.config.Close()
	}

	if z.dev != nil {
		z.dev.Close()
	}

	if z.ctx != nil {
		z.ctx.Close()
	}
}

func (z *Zedmon) read() []byte {
	ctx, done := context.WithTimeout(context.Background(), time.Second)
	defer done()
	buf := make([]byte, z.inEp.Desc.MaxPacketSize)
	len, err := z.readStream.ReadContext(ctx, buf)
	if err != nil {
		log.Printf("Read stream error: %v", err)
		return nil
	}
	return buf[:len]
}

// Synchronize with the device.
//
// It is possible for out endpoint data toggles to get out of phase on on
// successive invocations.  Repeating a get format report command until we
// get a response synchronizes them.
func (z *Zedmon) sync() {
	for {
		ctx, done := context.WithTimeout(context.Background(), time.Millisecond*100)
		defer done()

		data := make([]byte, 2)
		data[0] = 0x00
		data[1] = 0x00
		_, err := z.outEp.Write(data)
		if err != nil {
			log.Printf("Sync send error: %v", err)
			continue
		}
		buf := make([]byte, z.inEp.Desc.MaxPacketSize)
		_, err = z.inEp.ReadContext(ctx, buf)
		if err == nil {
			break
		}
		if usbErr, ok := err.(gousb.TransferStatus); ok && usbErr == gousb.TransferTimedOut {
			continue
		}
		log.Printf("Sync read error: %v", err)
	}
}

func (z *Zedmon) GetTimeOffset() (time.Duration, time.Duration, error) {
	bestRoundTripDuration := time.Duration(math.MaxInt64)
	bestOffset := time.Duration(0)

	for i := 0; i < 10; i++ {
		data := make([]byte, 1)
		data[0] = 0x01

		start := time.Now()
		_, err := z.outEp.Write(data)
		if err != nil {
			log.Printf("Sync Send Error: %v", err)
			return 0, 0, err
		}
		buf := z.read()
		if buf == nil {
			return 0, 0, fmt.Errorf("Can't read packet")
		}
		end := time.Now()
		reader := bytes.NewReader(buf[1:])
		var rawTimestamp uint64
		err = binary.Read(reader, binary.LittleEndian, &rawTimestamp)
		timestamp := time.Unix(int64(rawTimestamp/1000000), int64((rawTimestamp%1000000)*1000))

		delta := end.Sub(start)
		median := start.Add(delta / 2)
		offset := median.Sub(timestamp)

		if delta < bestRoundTripDuration {
			bestRoundTripDuration = delta
			bestOffset = offset
		}
	}

	return bestOffset, bestRoundTripDuration, nil
}

func (z *Zedmon) EnableReporting() error {
	data := make([]byte, 1)
	data[0] = PACKET_TYPE_ENABLE_REPORTING
	_, err := z.outEp.Write(data)
	if err != nil {
		return err
	}

	z.reportingEnabled = true

	return nil
}

func (z *Zedmon) DisableReporting() error {
	data := make([]byte, 1)
	data[0] = PACKET_TYPE_DISABLE_REPORTING
	_, err := z.outEp.Write(data)
	if err != nil {
		return err
	}

	// Give time for the packet to be sent.  This could be avoided by adding
	// ACKs to the protocol.
	time.Sleep(time.Millisecond * 100)

	z.reportingEnabled = false
	return nil
}

func (z *Zedmon) SetOuput(index uint8, value bool) error {
	packet := setOutputPacket{
		PacketType:  PACKET_TYPE_SET_OUTPUT,
		OutputIndex: index,
		OutputValue: value,
	}

	buf := new(bytes.Buffer)
	err := binary.Write(buf, binary.LittleEndian, &packet)
	if err != nil {
		return fmt.Errorf("SetOuput: binary.Write failed: %v", err)
	}

	_, err = z.outEp.Write(buf.Bytes())
	if err != nil {
		return err
	}

	// Give time for the packet to be sent.  This could be avoided by adding
	// ACKs to the protocol.
	time.Sleep(time.Millisecond * 100)

	return nil
}

// TODO: Add mechanism for pre-allocating reports.
func (z *Zedmon) ReadReports() ([]*Report, error) {
	buf := z.read()

	if buf[0] != PACKET_TYPE_REPORT {
		return nil, fmt.Errorf("Unexpected packet type: %02x", buf[0])
	}

	var reports []*Report

	reader := bytes.NewReader(buf[1:])
	for reader.Len() > 0 {
		var timestamp uint64
		err := binary.Read(reader, binary.LittleEndian, &timestamp)
		if err != nil {
			return nil, err
		}

		report := &Report{
			Timestamp: timestamp,
			Values:    make([]float64, 0, len(z.fields)),
		}

		for _, field := range z.fields {
			val, err := field.Decode(reader)
			if err != nil {
				return nil, err
			}
			report.Values = append(report.Values, val)
		}

		reports = append(reports, report)
	}

	return reports, nil
}

// Returns: offset after this field, error
func (z *Zedmon) getFormatReport(index uint, offset *int) (bool, error) {
	if index >= 0xff {
		return false, fmt.Errorf("Index %d out of range", index)
	}

	data := make([]byte, 2)
	data[0] = 0x00
	data[1] = uint8(index)
	numBytes, err := z.outEp.Write(data)
	if err != nil {
		return false, err
	}
	if numBytes != len(data) {
		return false, fmt.Errorf("Incomplete write %d != %d", numBytes, len(data))
	}

	response := z.read() //<-z.readChan
	var packet reportFormatPacket
	binary.Read(bytes.NewReader(response), binary.LittleEndian, &packet)

	if packet.ValueIndex == 0xff {
		return true, nil
	}

	dataType := DataType(packet.ValueType)
	if dataType.Size() < 0 {
		return false, fmt.Errorf("Can't handle Value type %d", dataType)
	}

	// TODO: validate Unit

	var name string
	n := bytes.IndexByte(packet.Name[:], 0x00)
	if n != -1 {
		name = string(packet.Name[:n])
	} else {
		name = string(packet.Name[:])
	}

	field := &Field{
		Offset: *offset,
		Name:   name,
		Type:   dataType,
		Unit:   Unit(packet.ValueUnit),
		Scale:  packet.Scale,
	}

	z.fields = append(z.fields, field)
	*offset += dataType.Size()

	return false, nil
}

func findZedmonInterface(dev *gousb.Device) (config int, intf int, setting int, err error) {
	for cfgNum, cfgDesc := range dev.Desc.Configs {
		for intfNum, intfDesc := range cfgDesc.Interfaces {
			for settingNum, settingDesc := range intfDesc.AltSettings {
				if settingDesc.Class == gousb.ClassVendorSpec &&
					settingDesc.SubClass == gousb.ClassVendorSpec &&
					settingDesc.Protocol == 0x0 &&
					len(settingDesc.Endpoints) == 2 {
					return cfgNum, intfNum, settingNum, nil
				}
			}
		}
	}
	return 0, 0, 0, fmt.Errorf("Can't find zedmon interface")
}

func (z *Zedmon) enumerateFields() error {
	offset := 0
	for i := uint(0); ; i++ {
		done, err := z.getFormatReport(i, &offset)
		if err != nil {
			return err
		}
		if done {
			return nil
		}
	}
}

func Enumerate() ([]Info, error) {
	ctx := gousb.NewContext()
	devs, err := ctx.OpenDevices(func(desc *gousb.DeviceDesc) bool {
		return desc.Vendor == 0x18d1 && desc.Product == 0xaf00
	})
	if err != nil {
		ctx.Close()
		return nil, err
	}

	if len(devs) == 0 {
		return nil, errors.New("No zedmon device found")
	}

	var infos []Info
	for _, d := range devs {
		serial, err := d.SerialNumber()
		if err != nil {
			continue
		}
		infos = append(infos, Info{Serial: serial})
	}

	return infos, nil
}

func OpenZedmon(config Config) (*Zedmon, error) {
	zedmon := &Zedmon{
		ctx: gousb.NewContext(),
	}

	devs, err := zedmon.ctx.OpenDevices(func(desc *gousb.DeviceDesc) bool {
		return desc.Vendor == 0x18d1 && desc.Product == 0xaf00
	})
	if err != nil {
		zedmon.Close()
		return nil, err
	}

	if len(devs) == 0 {
		return nil, errors.New("No zedmon device found")
	}

	var dev *gousb.Device
	if config.Serial == nil {
		dev = devs[0]
	} else {

		for _, d := range devs {
			serial, err := d.SerialNumber()
			if err != nil {
				continue
			}
			if serial == *config.Serial {
				dev = d
				break
			}
		}
		if dev == nil {
			zedmon.Close()
			return nil, fmt.Errorf("No zedmon device with serial %s found", *config.Serial)
		}
	}

	configNum, intfNum, settingNum, err := findZedmonInterface(dev)
	if err != nil {
		zedmon.Close()
		return nil, err
	}

	zedmon.config, err = dev.Config(configNum)
	if err != nil {
		zedmon.Close()
		return nil, err
	}

	zedmon.intf, err = zedmon.config.Interface(intfNum, settingNum)
	if err != nil {
		zedmon.Close()
		return nil, err
	}

	// TODO: We should verify this will succeed in findZedmonInterface().
	for _, epDesc := range zedmon.intf.Setting.Endpoints {
		switch epDesc.Direction {
		case gousb.EndpointDirectionIn:
			zedmon.inEpNum = epDesc.Number
		case gousb.EndpointDirectionOut:
			zedmon.outEpNum = epDesc.Number
		}
	}

	zedmon.inEp, err = zedmon.intf.InEndpoint(zedmon.inEpNum)
	if err != nil {
		zedmon.Close()
		return nil, err
	}

	zedmon.outEp, err = zedmon.intf.OutEndpoint(zedmon.outEpNum)
	if err != nil {
		zedmon.Close()
		return nil, err
	}

	zedmon.sync()

	zedmon.readStream, err = zedmon.inEp.NewStream(zedmon.inEp.Desc.MaxPacketSize, 100)
	if err != nil {
		zedmon.Close()
		return nil, err
	}

	zedmon.enumerateFields()

	return zedmon, nil
}
