#!/usr/bin/env python3
# Copyright 2023 The Pigweed 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
#
#     https://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.
"""Find serial ports."""

import argparse
import operator
import sys
from typing import Optional, Sequence

from serial.tools.list_ports import comports
from serial.tools.list_ports_common import ListPortInfo


def _parse_args():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument(
        '-l',
        '--list-ports',
        action='store_true',
        help='List all port info.',
    )
    parser.add_argument(
        '-p',
        '--product',
        help='Print ports matching this product name.',
    )
    parser.add_argument(
        '-s',
        '--serial-number',
        help='Print ports matching this serial number.',
    )
    parser.add_argument(
        '-1',
        '--print-first-match',
        action='store_true',
        help='Print the first port found sorted by device path.',
    )
    return parser.parse_args()


def _print_ports(ports: Sequence[ListPortInfo]):
    for cp in ports:
        for line in [
            f"device        = {cp.device}",
            f"name          = {cp.name}",
            f"description   = {cp.description}",
            f"vid           = {cp.vid}",
            f"pid           = {cp.pid}",
            f"serial_number = {cp.serial_number}",
            f"location      = {cp.location}",
            f"manufacturer  = {cp.manufacturer}",
            f"product       = {cp.product}",
            f"interface     = {cp.interface}",
        ]:
            print(line)
        print()


def main(
    list_ports: bool = False,
    product: Optional[str] = None,
    serial_number: Optional[str] = None,
    print_first_match: bool = False,
) -> int:
    """List all device info or print matches."""
    ports = sorted(comports(), key=operator.attrgetter('device'))

    if list_ports:
        _print_ports(ports)
        return 0

    any_match_found = False

    # Print matching devices
    for port in ports:
        if (
            product is not None
            and port.product is not None
            and product in port.product
        ):
            any_match_found = True
            print(port.device)

        if (
            serial_number is not None
            and port.serial_number is not None
            and serial_number in port.serial_number
        ):
            any_match_found = True
            print(port.device)

        if any_match_found and print_first_match:
            return 0

    if not any_match_found:
        return 1

    return 0


if __name__ == '__main__':
    sys.exit(main(**vars(_parse_args())))
