{
    "name"  : "端口双工/速率与自协商模式是否正确配置",
    "problems" : {
        "negotiation" : {
            "desc"      : "【问题】端口${0}自协商模式配置错误",
            "advice"    : ["【建议】打开自协商配置模式"
                          ,"配置举例："
                          ,"\tRuijie#config"
                          ,"\tRuijie(config)#interface ${1}"
                          ,"\tRuijie(config-if)#negotiation mode on"
                          ,"\tRuijie(config-if)#speed auto"
                          ,"\tRuijie(config-if)#duplex auto"
                          ,"\tRuijie(config-if)#end"
                          ,"\tRuijie#write"]
        },
        "ten" : {
            "desc"      : "【问题】端口${0}自协商模式配置错误", 
            "advice"    : ["【建议】端口${1}上开启了自协商功能，按照协议标准，万兆以上端口需要关闭自协商才能正常LINKUP。打开自协商配置模式。"
                          ,"配置举例："
                          ,"\tRuijie#config"
                          ,"\tRuijie(config)#interface ${2}"
                          ,"\tRuijie(config-if)#negotiation mode off"
                          ,"\tRuijie(config-if)#end"
                          ,"\tRuijie#write"]
        },
        "speed" : {
            "desc"      : "【问题】端口${0}双工/速率配置错误",
            "advice"    : ["【建议】建议修改双工速率模式。"
                          ,"配置示例："
                          ,"\tRuijie#config"
                          ,"\tRuijie(config)#interface ${1}"
                          ,"\tRuijie(config-if)#negotiation mode off"
                          ,"\tRuijie(config-if)#speed ${2}" 
                          ,"\tRuijie(config-if)#duplex ${3}"
                          ,"\tRuijie(config-if)#end"
                          ,"\tRuijie#write"]
        }
    },
    "conf" : {
        "if_ten" : [
            {"speed":"10G","duplex":"full"},
            {"speed":"1000","duplex":"full"}
        ],
        "if_gi" : [
            {"speed":"1000","duplex":"full"},
            {"speed":"100","duplex":"full"},
            {"speed":"10","duplex":"full"}
        ],
        "if_fa" : [
            {"speed":"100","duplex":"full"},
            {"speed":"10","duplex":"full"}
        ]
    }
}
---------------------------code-------------------------------
#端口双工/速率与自协商模式是否正确配置
param = {}
param["status"] = precondition('status')
param["type"] = precondition('type')
param["name"] = precondition('name')
model = get_device_model()

if_speed = ''
if_duplex = ''
if_negotiation = ''
if_up = ""
items = undefined
name = param["name"]
showIntfCmd = format('show interface %s',name)
conf = get_configure_value('conf')

def jumpOut(proType):
    name = param["name"]
    restore_cmd = []

    if proType == null:
        return 'skip'
    end
    if proType == 'negotiation':
        restore_cmd.push("end")
        restore_cmd.push("config")
        cmd = "interface " + name
        restore_cmd.push(cmd)
        if if_negotiation != "": 
           restore_cmd.push("negotiation mode on")
        end        
        restore_cmd.push("speed auto")
        restore_cmd.push("duplex auto")
        restore_cmd.push("en")
        restore_cmd.push("write")
        add_problem('negotiation', [name, name], restore_cmd, [])
        return 'warn'
    end
    if proType == 'ten':
        restore_cmd.push("end")
        restore_cmd.push("config")
        cmd = "interface " + name
        restore_cmd.push(cmd)
        restore_cmd.push("negotiation mode off")      
        restore_cmd.push("en")
        restore_cmd.push("write")
        add_problem('ten', [name, name, name], restore_cmd, [])
        return 'warn'
    end
    if proType == 'speed':
        restore_cmd.push("end")
        restore_cmd.push("config")
        cmd = "interface " + name
        restore_cmd.push(cmd)
        if if_negotiation != "": 
           restore_cmd.push("negotiation mode off")
        end       
        cmd1 = format("speed %s",if_speed)
        cmd2 = format("duplex %s",if_duplex)
        restore_cmd.push("cmd1")
        restore_cmd.push("cmd2")
        restore_cmd.push("en")
        restore_cmd.push("write")
        add_problem('speed', [name, name, if_speed, if_duplex], restore_cmd, [])
        return 'warn'
    end
    return 'success'
end

def fourth():
    cmd1 = format("speed %s",if_speed)
    cmd2 = format("duplex %s",if_duplex)
    if if_negotiation != "" :
        cmd3 = format("negotiation mode %s",if_negotiation)
    end
    cmd4 = "end"
    response1 = cli(cmd1)
    response2 = cli(cmd2)
    response3 = cli(cmd3)
    cli("parallel-detection")
    response4 = cli(cmd4) 
    if isInvalidCli(response1) || isInvalidCli(response2) || isInvalidCli(response3) || isInvalidCli(response4) :
        return 'skip'    
    end
    return "success"    
end
i = 0
def doOnce() :
    name = param["name"]
    if i >= items.length: 
        res = fourth()
        return res
    end
    item = items[i]
    i = i + 1
    if item['speed'] == undefined || item['duplex'] == undefined:
        return "skip"
    end
    if if_negotiation != "":
        response = cli("negotiation mode off")
    end    
    speedTemp = item['speed']
    duplexTemp = item['duplex']
    cmd1 = format('speed %s', speedTemp)
    cmd2 = format('duplex %s', duplexTemp)
    response = cli(cmd1)
    if isInvalidCli(response):
        return 'skip' 
    end
    response = cli(cmd2)
    if isInvalidCli(response):
        return 'skip' 
    end
    sleep(4000)
    response = cli(showIntfCmd)
    if isInvalidCli(response):
        return 'skip' 
    end    
    if_up = undefined
    reg = format('%s is (?:administratively )?(up)', name)
    reg = newRegExp(reg, 'i')
    if response.match(reg) != null:
        if_up = response.match(reg)
        if_up = if_up[1]
    end
    if if_up != undefined:
        cmd1 = format('speed %s', speedTemp)
        cmd2 = format('duplex %s', duplexTemp)
        response = cli(cmd1)
        if isInvalidCli(response): 
            return 'skip' 
        end
        response = cli(cmd2)
        if isInvalidCli(response):
            return 'skip' 
        end
        if if_negotiation != "":
            cmd3 = format('negotiation mode %s', if_negotiation)
            response = cli(cmd3)
            if isInvalidCli(response):
                return 'skip' 
            end            
        end
        response = cli("end")
        if isInvalidCli(response):
            return 'skip' 
        end
        res = jumpOut('speed')
        return res
    else:
        doOnce()
    end
end
def third():
    name = param["name"]
    if_cfg_arg_name = ""
    if name.search(/tengigabitetnernet/i) != -1:
        if_cfg_arg_name = "if_ten"
    else if name.search(/gigabitethernet/i) != -1 :
        if_cfg_arg_name = "if_gi"
    else if name.search(/fastethernet/i) != -1 :
        if_cfg_arg_name = "if_fa"
    else:
        return "skip"
    end
    items = conf[if_cfg_arg_name]
    if items == undefined:
        add_reason('配置文件缺少相应配置')
        return "skip"
    end
    res = doOnce() 
    return res
end

def second(response):
    do_check = true
    name = param["name"]
    if model.match(/S86\d{2}E/) != null || name.search(/tengigabitethernet/i) == null || if_negotiation == 'off' || if_negotiation == "" : 
        do_check = false
    end
    if do_check:
        response = cli('negotiation mode off')
        sleep(4000)
        response = cli(showIntfCmd)
        if isInvalidCli(response):
            add_reason(showIntfCmd)
            return 'skip' 
        end
        reg = format('%s is (administratively )?up', name)
        reg = newRegExp(reg, 'i')
        responseArr = response.match(reg)
        if responseArr != null :
            if_up = responseArr[1]
            if if_negotiation != "":
                cmd3 = format('negotiation mode %s', if_negotiation)
                response3 = cli(cmd3)
                if isInvalidCli(response3) :
                    return 'skip'    
                end
            end
            cli("end")
            res = jumpOut('ten')
            return res
        else :
            if if_negotiation != "" :
                cmd1 = format("negotiation mode %s",if_negotiation)
            end
            cmd2 = format("speed %s",if_speed)
            cmd3 = format("duplex %s",if_duplex)
            response1 = cli(cmd1) 
            response2 = cli(cmd2)
            response3 = cli(cmd3)
            res = third() 
            return res
        end
    else:
        res = third()
        return res
    end
end

def first():
    response = cli(showIntfCmd)
    if isInvalidCli(response):
        add_reason(showIntfCmd)
        return 'skip' 
    end
    name = param["name"]
    reg = format('%s is (administratively )?up', name)
    reg = newRegExp(reg, 'i')
    if response.match(reg) != null:
        if if_negotiation != "" :
            cmd1 = format("negotiation mode %s",if_negotiation)
        end
        cmd2 = format("speed %s",if_speed)
        cmd3 = format("duplex %s",if_duplex)
        cmd4 = "end"
        response1 = cli(cmd1) 
        response2 = cli(cmd2)
        response3 = cli(cmd3)
        response4 = cli(cmd4)
        if isInvalidCli(response1) || isInvalidCli(response2) || isInvalidCli(response3) || isInvalidCli(response4):
            return 'skip'    
        end
        res = jumpOut('negotiation') 
        return res
    else:
        if if_negotiation != "" :
            cmd1 = format("negotiation mode %s",if_negotiation)
        end
        cmd2 = format("speed %s",if_speed)
        cmd3 = format("duplex %s",if_duplex)
        response1 = cli(cmd1) 
        response2 = cli(cmd2)
        response3 = cli(cmd3)
        res = second(response) 
        return res
    end
end

def start():
    if param["status"] == 'up': 
        res = jumpOut(null) 
        add_reason('端口处于up状态')
        return res
    end
    name = param["name"]
    if name.search(/fastethernet|gigabitethernet|tengigabitetnernet/i) == null:
        res = jumpOut(null)
        add_reason('端口类型不属于fastethernet|gigabitethernet|tengigabitetnernet')
        return res
    end
    intfCmd = format('interface %s', name) 
    response = cli("configure")
    response = cli(intfCmd)
    response = cli("no parallel-detection")
    response = cli(showIntfCmd)
    if_speedArr = response.match(/admin[ ]+speed[ ]+is[ ]+(\d+g?|[a-z]+)/i)
    if if_speedArr.length > 1:
        if_speed = if_speedArr[1]
    end
    if_duplexArr = response.match(/admin[ ]+duplex[ ]+(?:mode[ ]+)?is[ ]+(?:Force)*[ ]*(\w+)/i)
    if if_duplexArr.length > 1:
        if_duplex = if_duplexArr[1]        
    end
    if response.match(/admin[ ]+negotiation[ ]+(?:mode[ ]+)?is[ ]+(\w+)/i) != null:
        if_negotiationArr = response.match(/admin[ ]+negotiation[ ]+(?:mode[ ]+)?is[ ]+(\w+)/i)
        if if_negotiationArr.length > 1:
            if_negotiation = if_negotiationArr[1]
        end
    end   
    if if_duplex == '': 
        return "skip"
    end    
    response = cli('speed auto') 
    response = cli('duplex auto')
    if if_negotiation != '':
        response = cli('negotiation mode on')
    end
    sleep(4000)
    res = first()
    return res
end

start()