/*
 Copyright 2017 the original author or authors.

 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 api

import (
	"errors"
	"fmt"
	"net"
	"sync"

	"gerrit.opencord.org/abstract-olt/internal/pkg/impl"
	context "golang.org/x/net/context"
)

/*
Server instance of the grpc server
*/
type Server struct {
}

var syncChan chan bool
var isDirty bool

var runOnce sync.Once

func getSyncChannel() chan bool {
	runOnce.Do(func() {
		syncChan = make(chan bool, 1)
		syncChan <- true
	})

	return syncChan
}
func done(myChan chan bool, done bool) {
	myChan <- done
}

/*
Echo - Tester function which just returns same string sent to it
*/
func (s *Server) Echo(ctx context.Context, in *EchoMessage) (*EchoReplyMessage, error) {
	myChan := getSyncChannel()
	<-myChan
	defer done(myChan, true)
	fmt.Println("HELLO WTF")
	ping := in.GetPing()
	pong := EchoReplyMessage{Pong: ping}
	return &pong, nil
}

/*
CreateChassis - allocates a new Chassis struct and stores it in chassisMap
*/
func (s *Server) CreateChassis(ctx context.Context, in *AddChassisMessage) (*AddChassisReturn, error) {
	clli := in.GetCLLI()

	xosIP := net.ParseIP(in.GetXOSIP())
	xosPort := int(in.GetXOSPort())
	if xosIP == nil {
		errStr := fmt.Sprintf("Invalid IP %s supplied for XOSIP", in.GetXOSIP())
		return nil, errors.New(errStr)
	}
	xosAddress := net.TCPAddr{IP: xosIP, Port: xosPort}
	xosUser := in.GetXOSUser()
	xosPassword := in.GetXOSPassword()
	if xosUser == "" || xosPassword == "" {
		return nil, errors.New("Either XOSUser or XOSPassword supplied were empty")
	}
	shelf := int(in.GetShelf())
	rack := int(in.GetRack())
	deviceID, err := impl.CreateChassis(clli, xosAddress, xosUser, xosPassword, shelf, rack)
	if err != nil {
		return nil, err
	}
	return &AddChassisReturn{DeviceID: deviceID}, nil
}

/*
ChangeXOSUserPassword - allows update of xos credentials
*/
func (s *Server) ChangeXOSUserPassword(ctx context.Context, in *ChangeXOSUserPasswordMessage) (*ChangeXOSUserPasswordReturn, error) {
	clli := in.GetCLLI()
	xosUser := in.GetXOSUser()
	xosPassword := in.GetXOSPassword()
	if xosUser == "" || xosPassword == "" {
		return nil, errors.New("Either XOSUser or XOSPassword supplied were empty")
	}
	success, err := impl.ChangeXOSUserPassword(clli, xosUser, xosPassword)
	return &ChangeXOSUserPasswordReturn{Success: success}, err

}

/*
CreateOLTChassis adds an OLT chassis/line card to the Physical chassis
*/
func (s *Server) CreateOLTChassis(ctx context.Context, in *AddOLTChassisMessage) (*AddOLTChassisReturn, error) {
	clli := in.GetCLLI()
	oltType := in.GetType().String()
	address := net.TCPAddr{IP: net.ParseIP(in.GetSlotIP()), Port: int(in.GetSlotPort())}
	hostname := in.GetHostname()
	clli, err := impl.CreateOLTChassis(clli, oltType, address, hostname)
	return &AddOLTChassisReturn{DeviceID: hostname, ChassisDeviceID: clli}, err
}

/*
ProvisionOnt provisions an ONT on a specific Chassis/LineCard/Port
*/
func (s *Server) ProvisionOnt(ctx context.Context, in *AddOntMessage) (*AddOntReturn, error) {
	clli := in.GetCLLI()
	slotNumber := int(in.GetSlotNumber())
	portNumber := int(in.GetPortNumber())
	ontNumber := int(in.GetOntNumber())
	serialNumber := in.GetSerialNumber()
	success, err := impl.ProvisionOnt(clli, slotNumber, portNumber, ontNumber, serialNumber)
	return &AddOntReturn{Success: success}, err
}

/*
ProvsionOntFull - provisions ont using sTag,cTag,NasPortID, and CircuitID passed in
*/
func (s *Server) ProvisionOntFull(ctx context.Context, in *AddOntFullMessage) (*AddOntReturn, error) {
	clli := in.GetCLLI()
	slotNumber := int(in.GetSlotNumber())
	portNumber := int(in.GetPortNumber())
	ontNumber := int(in.GetOntNumber())
	serialNumber := in.GetSerialNumber()
	cTag := in.GetCTag()
	sTag := in.GetSTag()
	nasPortID := in.GetNasPortID()
	circuitID := in.GetCircuitID()
	success, err := impl.ProvisionOntFull(clli, slotNumber, portNumber, ontNumber, serialNumber, cTag, sTag, nasPortID, circuitID)
	return &AddOntReturn{Success: success}, err
}

/*
DeleteOnt - deletes a previously provision ont
*/
func (s *Server) DeleteOnt(ctx context.Context, in *DeleteOntMessage) (*DeleteOntReturn, error) {
	clli := in.GetCLLI()
	slotNumber := int(in.GetSlotNumber())
	portNumber := int(in.GetPortNumber())
	ontNumber := int(in.GetOntNumber())
	serialNumber := in.GetSerialNumber()
	success, err := impl.DeleteOnt(clli, slotNumber, portNumber, ontNumber, serialNumber)
	return &DeleteOntReturn{Success: success}, err
}

func (s *Server) Reflow(ctx context.Context, in *ReflowMessage) (*ReflowReturn, error) {
	success, err := impl.Reflow()
	return &ReflowReturn{Success: success}, err

}
func (s *Server) Output(ctx context.Context, in *OutputMessage) (*OutputReturn, error) {
	success, err := impl.DoOutput()
	return &OutputReturn{Success: success}, err

}
