// +build !windows

/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 bll

import (
	"fmt"
	"sync"

	log "github.com/Sirupsen/logrus"
	"github.com/go-ble/ble"
	"github.com/runtimeco/go-coap"
	"golang.org/x/net/context"

	"mynewt.apache.org/newt/util"
	"mynewt.apache.org/newtmgr/newtmgr/nmutil"
	"mynewt.apache.org/newtmgr/nmxact/bledefs"
	"mynewt.apache.org/newtmgr/nmxact/mgmt"
	"mynewt.apache.org/newtmgr/nmxact/nmble"
	"mynewt.apache.org/newtmgr/nmxact/nmcoap"
	"mynewt.apache.org/newtmgr/nmxact/nmp"
	"mynewt.apache.org/newtmgr/nmxact/nmxutil"
	"mynewt.apache.org/newtmgr/nmxact/sesn"
)

// A session that uses the host machine's native BLE support.
type BllSesn struct {
	cfg BllSesnCfg

	// The native BLE client.  All accesses must be protected by the mutex.
	cln ble.Client

	txvr   *mgmt.Transceiver
	mtx    sync.Mutex
	attMtu uint16

	nmpReqChr    *ble.Characteristic
	nmpRspChr    *ble.Characteristic
	publicReqChr *ble.Characteristic
	publicRspChr *ble.Characteristic
	unauthReqChr *ble.Characteristic
	unauthRspChr *ble.Characteristic
	secureReqChr *ble.Characteristic
	secureRspChr *ble.Characteristic

	txFilterCb nmcoap.MsgFilter
	rxFilterCb nmcoap.MsgFilter
}

func NewBllSesn(cfg BllSesnCfg) *BllSesn {
	return &BllSesn{
		cfg:        cfg,
		txFilterCb: cfg.TxFilterCb,
		rxFilterCb: cfg.RxFilterCb,
	}
}

func (s *BllSesn) getCln() (ble.Client, error) {
	s.mtx.Lock()
	defer s.mtx.Unlock()

	if s.cln == nil {
		return nil, fmt.Errorf("disconnected")
	}

	return s.cln, nil
}

func (s *BllSesn) setCln(c ble.Client) {
	s.mtx.Lock()
	defer s.mtx.Unlock()

	s.cln = c
}

func (s *BllSesn) listenDisconnect() {
	go func() {
		cln, err := s.getCln()
		if err != nil {
			return
		}

		<-cln.Disconnected()
		s.txvr.ErrorAll(fmt.Errorf("disconnected"))
		s.txvr.Stop()
		s.setCln(nil)
	}()
}

func (s *BllSesn) txConnect(f ble.AdvFilter) (ble.Client, error) {
	ctx := ble.WithSigHandler(context.WithTimeout(context.Background(),
		s.cfg.ConnTimeout))

	client, err := ble.Connect(ctx, s.cfg.AdvFilter)
	if err != nil {
		if nmutil.ErrorCausedBy(err, context.DeadlineExceeded) {
			return nil, fmt.Errorf("Failed to connect to peer after %s",
				s.cfg.ConnTimeout.String())
		} else {
			return nil, err
		}
	}

	return client, nil
}

func (s *BllSesn) txDiscoverProfile() (*ble.Profile, error) {
	cln, err := s.getCln()
	if err != nil {
		return nil, err
	}

	return cln.DiscoverProfile(true)
}

func (s *BllSesn) txSubscribe(
	c *ble.Characteristic,
	ind bool,
	fn ble.NotificationHandler) error {

	cln, err := s.getCln()
	if err != nil {
		return err
	}
	return cln.Subscribe(c, ind, fn)
}

func (s *BllSesn) txExchangeMtu(mtu uint16) (uint16, error) {
	cln, err := s.getCln()
	if err != nil {
		return 0, err
	}
	return exchangeMtu(cln, uint16(mtu))
}

func (s *BllSesn) txCancelConnection() error {
	cln, err := s.getCln()
	if err != nil {
		return err
	}
	return cln.CancelConnection()
}

func (s *BllSesn) txWriteCharacteristic(
	c *ble.Characteristic,
	b []byte,
	noRsp bool) error {

	cln, err := s.getCln()
	if err != nil {
		return err
	}
	return cln.WriteCharacteristic(c, b, noRsp)
}

func (s *BllSesn) connect() error {
	log.Debugf("Connecting to peer")

	cln, err := s.txConnect(s.cfg.AdvFilter)
	if err != nil {
		if nmutil.ErrorCausedBy(err, context.DeadlineExceeded) {
			return fmt.Errorf("Failed to connect to peer after %s",
				s.cfg.ConnTimeout.String())
		} else {
			return err
		}
	}

	s.setCln(cln)
	s.listenDisconnect()

	return nil
}

func findChr(profile *ble.Profile, chrId *bledefs.BleChrId) (
	*ble.Characteristic, error) {

	if chrId == nil {
		return nil, fmt.Errorf("BLE session not configured with required " +
			"characteristic")
	}

	for _, s := range profile.Services {
		uuid, err := UuidFromBllUuid(s.UUID)
		if err != nil {
			return nil, err
		}

		if bledefs.CompareUuids(uuid, chrId.SvcUuid) == 0 {
			for _, c := range s.Characteristics {
				uuid, err := UuidFromBllUuid(c.UUID)
				if err != nil {
					return nil, err
				}

				if bledefs.CompareUuids(uuid, chrId.ChrUuid) == 0 {
					return c, nil
				}
			}
		}
	}

	return nil, nil
}

func (s *BllSesn) discoverAll() error {
	log.Debugf("Discovering profile")

	p, err := s.txDiscoverProfile()
	if err != nil {
		return err
	}

	mgmtChrs, err := nmble.BuildMgmtChrs(s.cfg.MgmtProto)
	if err != nil {
		return err
	}

	s.nmpReqChr, _ = findChr(p, mgmtChrs.NmpReqChr)
	s.nmpRspChr, _ = findChr(p, mgmtChrs.NmpRspChr)
	s.publicReqChr, _ = findChr(p, mgmtChrs.ResPublicReqChr)
	s.publicRspChr, _ = findChr(p, mgmtChrs.ResPublicRspChr)
	s.unauthReqChr, _ = findChr(p, mgmtChrs.ResUnauthReqChr)
	s.unauthRspChr, _ = findChr(p, mgmtChrs.ResUnauthRspChr)
	s.secureReqChr, _ = findChr(p, mgmtChrs.ResSecureReqChr)
	s.secureRspChr, _ = findChr(p, mgmtChrs.ResSecureRspChr)

	return nil
}

// Subscribes to the peer's characteristic implementing NMP.
func (s *BllSesn) subscribe() error {
	log.Debugf("Subscribing to NMP response characteristic")

	onNotify := func(data []byte) {
		s.txvr.DispatchNmpRsp(data)
	}

	if s.nmpRspChr != nil {
		if err := s.txSubscribe(s.nmpRspChr, false, onNotify); err != nil {
			return err
		}
	}

	if s.publicRspChr != nil {
		if err := s.txSubscribe(s.publicRspChr, false, onNotify); err != nil {
			return err
		}
	}

	if s.unauthRspChr != nil {
		if err := s.txSubscribe(s.unauthRspChr, false, onNotify); err != nil {
			return err
		}
	}

	if s.secureRspChr != nil {
		if err := s.txSubscribe(s.secureRspChr, false, onNotify); err != nil {
			return err
		}
	}

	return nil
}

func (s *BllSesn) exchangeMtu() error {
	mtu, err := s.txExchangeMtu(s.cfg.PreferredMtu)
	if err != nil {
		return err
	}

	s.attMtu = mtu
	return nil
}

// @return bool                 Whether to retry the open attempt; false
//                                  on success.
//         error                The cause of a failed open; nil on success.
func (s *BllSesn) openOnce() (bool, error) {
	if s.IsOpen() {
		return false, nmxutil.NewSesnAlreadyOpenError(
			"Attempt to open an already-open bll session")
	}

	txvr, err := mgmt.NewTransceiver(s.txFilterCb, s.rxFilterCb, true, s.cfg.MgmtProto, 3)
	if err != nil {
		return false, err
	}
	s.txvr = txvr

	if err := s.connect(); err != nil {
		return false, err
	}

	if err := s.exchangeMtu(); err != nil {
		return true, err
	}

	if err := s.discoverAll(); err != nil {
		return false, err
	}

	if err := s.subscribe(); err != nil {
		return false, err
	}

	return false, nil
}

func (s *BllSesn) Open() error {
	var err error

	for i := 0; i < s.cfg.ConnTries; i++ {
		var retry bool

		retry, err = s.openOnce()
		if err != nil {
			// Ensure the session is closed.
			s.Close()
		}

		if !retry {
			break
		}
	}

	return err
}

func (s *BllSesn) Close() error {
	if !s.IsOpen() {
		return nmxutil.NewSesnClosedError(
			"Attempt to close an unopened bll session")
	}

	if err := s.txCancelConnection(); err != nil {
		return err
	}

	s.setCln(nil)
	return nil
}

// Indicates whether the session is currently open.
func (s *BllSesn) IsOpen() bool {
	cln, _ := s.getCln()
	return cln != nil
}

// Retrieves the maximum data payload for incoming NMP responses.
func (s *BllSesn) MtuIn() int {
	return int(s.attMtu) - nmble.NOTIFY_CMD_BASE_SZ
}

// Retrieves the maximum data payload for outgoing NMP requests.
func (s *BllSesn) MtuOut() int {
	return util.IntMin(s.MtuIn(), bledefs.BLE_ATT_ATTR_MAX_LEN)
}

// Stops a receive operation in progress.  This must be called from a
// separate thread, as sesn receive operations are blocking.
func (s *BllSesn) AbortRx(nmpSeq uint8) error {
	s.txvr.ErrorOne(nmpSeq, fmt.Errorf("Rx aborted"))
	return nil
}

func (s *BllSesn) RxAccept() (sesn.Sesn, *sesn.SesnCfg, error) {
	return nil, nil, fmt.Errorf("Op not implemented yet")
}

func (s *BllSesn) RxCoap(opt sesn.TxOptions) (coap.Message, error) {
	return nil, fmt.Errorf("Op not implemented yet")
}

// Performs a blocking transmit a single NMP message and listens for the
// response.
//     * nil: success.
//     * nmxutil.SesnClosedError: session not open.
//     * other error
func (s *BllSesn) TxNmpOnce(msg *nmp.NmpMsg, opt sesn.TxOptions) (
	nmp.NmpRsp, error) {

	if !s.IsOpen() {
		return nil, nmxutil.NewSesnClosedError(
			"Attempt to transmit over closed BLE session")
	}

	if s.nmpReqChr == nil || s.nmpRspChr == nil {
		return nil, fmt.Errorf("Cannot send NMP request; peer doesn't " +
			"support request or response characteristic")
	}

	txRaw := func(b []byte) error {
		return s.txWriteCharacteristic(s.nmpReqChr, b, true)
	}

	return s.txvr.TxNmp(txRaw, msg, s.MtuOut(), opt.Timeout)
}

func (s *BllSesn) resReqChr(resType sesn.ResourceType) (
	*ble.Characteristic, error) {

	m := map[sesn.ResourceType]*ble.Characteristic{
		sesn.RES_TYPE_PUBLIC: s.publicReqChr,
		sesn.RES_TYPE_UNAUTH: s.unauthReqChr,
		sesn.RES_TYPE_SECURE: s.secureReqChr,
	}

	chr := m[resType]
	if chr == nil {
		return nil, fmt.Errorf("BLE session not configured with "+
			"characteristic for %s resources", resType)
	}

	return chr, nil
}

func (s *BllSesn) TxCoapOnce(m coap.Message, resType sesn.ResourceType,
	opt sesn.TxOptions) (coap.COAPCode, []byte, error) {

	chr, err := s.resReqChr(resType)
	if err != nil {
		return 0, nil, err
	}

	txRaw := func(b []byte) error {
		return s.txWriteCharacteristic(chr, b, !s.cfg.WriteRsp)
	}

	rsp, err := s.txvr.TxOic(txRaw, m, s.MtuOut(), opt.Timeout)
	if err != nil {
		return 0, nil, err
	} else if rsp == nil {
		return 0, nil, nil
	} else {
		return rsp.Code(), rsp.Payload(), nil
	}
}

func (s *BllSesn) TxCoapObserve(m coap.Message, resType sesn.ResourceType,
	opt sesn.TxOptions, NotifCb sesn.GetNotifyCb, stopsignal chan int) (coap.COAPCode, []byte, []byte, error) {
	chr, err := s.resReqChr(resType)
	if err != nil {
		return 0, nil, nil, err
	}

	txRaw := func(b []byte) error {
		return s.txWriteCharacteristic(chr, b, !s.cfg.WriteRsp)
	}

	rsp, err := s.txvr.TxOicObserve(txRaw, m, s.MtuOut(), opt.Timeout, NotifCb, stopsignal)
	if err != nil {
		return 0, nil, nil, err
	} else if rsp == nil {
		return 0, nil, nil, nil
	} else {
		return rsp.Code(), rsp.Payload(), rsp.Token(), nil
	}
}

func (s *BllSesn) MgmtProto() sesn.MgmtProto {
	return s.cfg.MgmtProto
}

func (s *BllSesn) CoapIsTcp() bool {
	return true
}

func (s *BllSesn) Filters() (nmcoap.MsgFilter, nmcoap.MsgFilter) {
	return s.txFilterCb, s.rxFilterCb
}
