import typing as t

import module.device.method.scrcpy.const as const


class ScrcpyOptions:
    frame_rate = 10

    @classmethod
    def codec_options(cls) -> str:
        """
        Custom codec options passing through scrcpy.
        https://developer.android.com/reference/android/media/MediaFormat

        Returns:
            key_profile=1,key_level=4096,...
        """
        options = dict(
            # H.264 profile and level
            # https://developer.android.com/reference/android/media/MediaCodecInfo.CodecProfileLevel
            # Baseline, which only has I/P frames
            key_profile=1,
            # Level 4.1, for 1280x720@30fps
            key_level=4096,
            # Max quality
            key_quality=100,
            # https://developer.android.com/reference/android/media/MediaCodecInfo.EncoderCapabilities
            # Constant quality
            key_bitrate_mode=0,
            # A zero value means a stream containing all key frames is requested.
            key_i_frame_interval=0,
            # https://developer.android.com/reference/android/media/MediaCodecInfo.CodecCapabilities
            # COLOR_Format24bitBGR888
            key_color_format=12,
            # The same as output frame rate to lower CPU consumption
            key_capture_rate=cls.frame_rate,
            # 20Mbps, the maximum output bitrate of scrcpy
            key_bit_rate=20000000,
        )
        return ','.join([f'{k}={v}' for k, v in options.items()])

    @classmethod
    def arguments(cls) -> t.List[str]:
        """
        https://github.com/Genymobile/scrcpy/blob/master/server/src/main/java/com/genymobile/scrcpy/Server.java
        https://github.com/Genymobile/scrcpy/blob/master/server/src/main/java/com/genymobile/scrcpy/Options.java

        Returns:
            ['log_level=info', 'max_size=1280', ...]
        """
        options = [
            'log_level=info',
            'max_size=1280',
            # 20Mbps, the maximum output bitrate of scrcpy
            # If a higher value is set, scrcpy fallback to 8Mbps default.
            'bit_rate=20000000',
            # Screenshot time cost <= 300ms is enough for human speed.
            f'max_fps={cls.frame_rate}',
            # No orientation lock
            f'lock_video_orientation={const.LOCK_SCREEN_ORIENTATION_UNLOCKED}',
            # Always true
            'tunnel_forward=true',
            # Always true for controlling via scrcpy
            'control=true',
            # Default to 0
            'display_id=0',
            # Useless, always false
            'show_touches=false',
            # Not determined, leave it as default
            'stay_awake=false',
            # Encoder name
            # Should in [
            #     "OMX.google.h264.encoder",
            #     "OMX.qcom.video.encoder.avc",
            #     "c2.qti.avc.encoder",
            #     "c2.android.avc.encoder",
            # ]
            # Empty value, let scrcpy to decide
            # 'encoder_name=',
            # Codec options
            f'codec_options={cls.codec_options()}',
            # Useless, always false
            'power_off_on_close=false',
            'clipboard_autosync=false',
            'downsize_on_error=false',
        ]
        return options

    @classmethod
    def command_v125(cls, jar_path='/data/local/tmp/scrcpy-server.jar') -> t.List[str]:
        """
        Generate the commands to run scrcpy.
        """
        commands = [
            f'CLASSPATH={jar_path}',
            'app_process',
            '/',
            'com.genymobile.scrcpy.Server',
            '1.25',
        ]
        commands += cls.arguments()
        return commands

    @classmethod
    def command_v120(cls, jar_path='/data/local/tmp/scrcpy-server.jar') -> t.List[str]:
        commands = [
            f"CLASSPATH={jar_path}",
            "app_process",
            "/",
            "com.genymobile.scrcpy.Server",
            "1.20",  # Scrcpy server version
            "info",  # Log level: info, verbose...
            f"1280",  # Max screen width (long side)
            f"20000000",  # Bitrate of video
            f"{cls.frame_rate}",  # Max frame per second
            f"{const.LOCK_SCREEN_ORIENTATION_UNLOCKED}",  # Lock screen orientation: LOCK_SCREEN_ORIENTATION
            "true",  # Tunnel forward
            "-",  # Crop screen
            "false",  # Send frame rate to client
            "true",  # Control enabled
            "0",  # Display id
            "false",  # Show touches
            "false",  # Stay awake
            cls.codec_options(),  # Codec (video encoding) options
            "-",  # Encoder name
            "false",  # Power off screen after server closed
        ]
        return commands


if __name__ == '__main__':
    print(' '.join(ScrcpyOptions.command_v120()))
