def _duplex(port_data):
    """Return duplex value for port.

    Args:
        port_data: Data dict related to the port

    Returns:
        duplex: Duplex value
            0) Unknown
            1) Half
            2) Full
            3) Half Auto
            4) Full Auto

    """
    # Initialize key variables
    duplex = 0

    value = ''

    statuses = ('swPortDuplexStatus',
                'dot3StatsDuplexStatus',
                'portDuplex')

    def get_duplex_value(status, val):
        """Return duplex value based on port status.

        Args:
            status: The status of the port
            value: The value of the port status

        Returns:
            value: Duplex value

        """
        cases = {
            'swPortDuplexStatus': 2 if val == 1 else 1,
            'dot3StatsDuplexStatus': 1 if val == 2 else (2 if val == 3 else 0),
            'portDuplex': 1 if val == 1 else (2 if val == 2 else 0),
        }

        return cases[status]

    for status in statuses:
        if status in port_data:
            value = port_data[status]
            duplex = get_duplex_value(status, value)
            break

    # Process c2900PortDuplexState
    # The Cisco 3500XL is known to report incorrect duplex values.
    # Obsolete device, doesn't make sense supporting it.
    if not duplex and 'c2900PortLinkbeatStatus' in port_data:
        status_link = port_data['c2900PortLinkbeatStatus']
        status_duplex = port_data['c2900PortDuplexStatus']

        if status_link == 3:
            # If no link beats (Not AutoNegotiate)
            if status_duplex == 1:
                duplex = 2
            elif status_duplex == 2:
                duplex = 1
        else:
            # If link beats (AutoNegotiate)
            if status_duplex == 1:
                duplex = 4
            elif status_duplex == 2:
                duplex = 3

    # Return
    return duplex