#!/usr/bin/env python3
# @file testWR.py
#
# @brief Check the correct operation of White Rabbit
#
# @author Manuel Castilla
# @date 23/04/2019
#
# Copyright (c) 2019 CERN (www.cern.ch).
#
# This file is part of WR Starting Kit project
# (see https://www.ohwr.org/project/wr-starting-kit).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
#(at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
###########################################################################

from vuart import Vuart
import configparser
import time


def whoIsMaster(hostName,userName,password,busId):
    """
    This function asks which spec has SFP purple (master)

    Args:
        hostName: ip remote host
        username: user name
        password: password
        busId: number PCIe bus

    Return:
        True if the spec has SFP purple, False otherwise
    """
    ret = False
    try:
        vuart = Vuart(hostName,userName,password,busId)
        value = vuart.sfpDetect()
        if ("AXGE-3454-0531" in value):
            ret = True
    except:
        print("Who is master: error, host:",hostName)
        raise

    return ret

def putMode(hostName,userName,password,busId,mode):
    """
    This function puts in mode master an spec

    Args:
        hostName: ip remote host
        username: user name
        password: password
        busId: number PCIe bus
        mode: mode ptp status("master","slave")

    Raises:
        error function
    """
    try:
        vuart = Vuart(hostName,userName,password,busId)
        if (mode == "master"):
            vuart.modeMaster()
        else:
            vuart.modeSlave()

        vuart.ptpStart()
        value = vuart.mode()
        if(mode in value):
            print("Put mode", mode,": ok, host:",hostName)
        else:
            raise
    except:
        print("Put mode: error, host:",hostName)
        raise


def checkTrackPhase(hostName,userName,password,busId):
    """
    This function check if the state is TRACK_PHASE

    Args:
        hostName: ip remote host
        username: user name
        password: password
        busId: number PCIe bus
    Raises:
        error function
    """
    try:
        vuart = Vuart(hostName,userName,password,busId)
        numberTimesTry = 15
        i = 0
        while not vuart.isTrackPhase():
            if (i == numberTimesTry):
                raise
            i = i + 1
            time.sleep(1)
        print("Track Phase: ok")
    except:
        print("Track phase: error, host:",hostName)
        raise

#--------------------------------------------------#
#--------------------------------------------------#
# MAIN
#--------------------------------------------------#
#--------------------------------------------------#
def main(configuration):
    hostName1 = configuration["hostName1"]
    userName1 = configuration["userName1"]
    password1 = configuration["password1"]
    busIdSpec1 = configuration["busIdSpec1"]
    interfaceName1 = configuration["interfaceName1"]
    hostName2 = configuration["hostName2"]
    userName2 = configuration["userName2"]
    password2 = configuration["password2"]
    busIdSpec2 = configuration["busIdSpec2"]
    interfaceName2 = configuration["interfaceName2"]

    try:
        print("\nExecuting WR test")
        masterSpec1 = whoIsMaster(hostName1,userName1,password1,busIdSpec1)
        masterSpec2 = whoIsMaster(hostName2,userName2,password2,busIdSpec2)
        if (masterSpec1 == 1 or masterSpec2 == 1):
            if (masterSpec1 == 1):
                putMode(hostName2,userName2,password2,busIdSpec2,"slave")
                putMode(hostName1,userName1,password1,busIdSpec1,"master")
                checkTrackPhase(hostName2,userName2,password2,busIdSpec2)
            else:
                putMode(hostName1,userName1,password1,busIdSpec1,"slave")
                putMode(hostName2,userName2,password2,busIdSpec2,"master")
                checkTrackPhase(hostName1,userName1,password1,busIdSpec1)

            print("Test WR: successful")
        else:
            print("Error: It is not possible to know who is master")
            raise
    except:
        print("Test WR: error")

if __name__ == '__main__':
    try:
        configuration = {}
        nameConfig = "configuration.cfg"

        config = configparser.ConfigParser()
        config.readfp(open(nameConfig))

        configuration["hostName1"] = config.get('pc1',"hostName")
        configuration["userName1"] = config.get('pc1',"userName")
        configuration["password1"] = config.get('pc1',"password")
        configuration["busIdSpec1"] = config.get('pc1',"busIdSpec")
        configuration["interfaceName1"] = config.get('pc1',"interfaceName")
        configuration["hostName2"] = config.get('pc2',"hostName")
        configuration["userName2"] = config.get('pc2',"userName")
        configuration["password2"] = config.get('pc2',"password")
        configuration["busIdSpec2"] = config.get('pc2',"busIdSpec")
        configuration["interfaceName2"] = config.get('pc2',"interfaceName")

        main(configuration)
    except configparser.Error as e:
        print("Error load configuration:",e.message)
