#!/usr/bin/python -u

"""
Copyright (C) 2017 Jacksgong(jacksgong.com)

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

   http://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.
"""
import argparse
from sys import argv

from okcat.adb import Adb
from okcat.helper import LOG_LEVELS, is_path
from okcat.logfile_parser import LogFileParser
from okcat.terminalcolor import print_tips, print_blue, print_warn, print_header, print_exit

__author__ = 'JacksGong'
__version__ = '1.5.0'
__description__ = 'This python script used for combine several Android projects to one project.'


def main():
    print("-------------------------------------------------------")
    print("                  OkCat v" + __version__)
    print("")
    print("Thanks for using okcat! Now, the doc is available on: ")
    print_blue("        https://github.com/Jacksgong/okcat")
    print("")
    print("                   Have Fun!")
    print("-------------------------------------------------------")

    parser = argparse.ArgumentParser(
        description='强大的日志处理工具 - 支持 Android ADB Logcat 和任意格式日志文件解析',
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog='''
使用示例:
  # ADB 模式 - 过滤包含特定关键词的日志
  okcat -k abc -k cde com.example.app
  
  # ADB 模式 - 包名支持部分匹配
  okcat example          # 匹配包含 "example" 的包名
  okcat com.example      # 匹配包含 "com.example" 的包名
  
  # ADB 模式 - 过滤 tag 包含关键词的日志
  okcat -tk FileDownloader com.example.app
  
  # 文件模式 - 解析日志文件
  okcat -y=my-config logfile.txt
  
  # 组合使用 - 多个过滤条件
  okcat -k error -tk MyTag -l E com.example.app

更多信息: https://github.com/Jacksgong/okcat
        '''
    )
    
    parser.add_argument('package_or_path', nargs='*',
                        help='应用包名(ADB模式) 或 日志文件路径(文件模式)。\n'
                             '包名支持部分匹配（包含匹配），例如: \n'
                             '  - okcat example          # 匹配包含 "example" 的包名\n'
                             '  - okcat com.example      # 匹配包含 "com.example" 的包名\n'
                             '  - okcat com.example.app  # 完整匹配\n'
                             '日志文件路径示例: /path/to/logfile.log')

    # 配置和通用选项
    config_group = parser.add_argument_group('配置选项', '配置文件和通用设置')
    config_group.add_argument('-y', '--yml_file_name', dest='yml', metavar='CONF_NAME',
                             help='使用配置文件(无需 .yml 后缀)。\n'
                                  '会先查找当前目录，找不到则在 ~/.okcat/ 目录查找')
    config_group.add_argument('--hide-same-tags', dest='hide_same_tags', action='store_true',
                             help='隐藏相同的 tag 名称，减少重复显示')

    # 过滤选项
    filter_group = parser.add_argument_group('过滤选项', '根据关键词、标签等条件过滤日志')
    filter_group.add_argument('-k', '--keyword', dest='keyword', action='append', metavar='KEYWORD',
                             help='过滤日志消息内容中的关键词(可多次使用)。\n'
                                  '示例: -k abc -k cde  (显示包含 "abc" 或 "cde" 的日志行)\n'
                                  '注意: 这是过滤消息正文内容，不是过滤 tag')
    filter_group.add_argument('-tk', '--tag_keywords', dest='tag_keywords', action='append', metavar='TAG_KEYWORD',
                             help='过滤日志 tag 中包含的关键词(可多次使用)。\n'
                                  '示例: -tk FileDownloader -tk Network  (显示 tag 包含这些关键词的日志)\n'
                                  '注意: 这是过滤 tag，不是过滤消息内容')
    filter_group.add_argument('-t', '--tag', dest='tag', action='append', metavar='TAG',
                             help='精确匹配指定的 tag(可多次使用)\n'
                                  '示例: -t MyTag -t AnotherTag')
    filter_group.add_argument('-i', '--ignore-tag', dest='ignored_tag', action='append', metavar='TAG',
                             help='忽略指定的 tag(可多次使用)\n'
                                  '示例: -i NoiseTag -i DebugTag')
    filter_group.add_argument('-l', '--min-level', dest='min_level', type=str, 
                             choices=LOG_LEVELS + LOG_LEVELS.lower(),
                             default='V', metavar='LEVEL',
                             help='最低日志级别: V(Verbose), D(Debug), I(Info), W(Warning), E(Error), F(Fatal)\n'
                                  '默认: V (显示所有级别)')
    filter_group.add_argument('-a', '--all', dest='all', action='store_true', default=False,
                             help='显示所有日志消息，忽略包名过滤')

    # ADB 设备选项
    adb_device_group = parser.add_argument_group('ADB 设备选项', '控制使用哪个 Android 设备')
    adb_device_group.add_argument('-s', '--serial', dest='device_serial', metavar='DEVICE_SERIAL',
                                 help='指定设备的序列号 (等同于 adb -s)')
    adb_device_group.add_argument('-d', '--device', dest='use_device', action='store_true',
                                 help='使用第一个已连接的设备 (等同于 adb -d)')
    adb_device_group.add_argument('-e', '--emulator', dest='use_emulator', action='store_true',
                                 help='使用第一个已连接的模拟器 (等同于 adb -e)')
    adb_device_group.add_argument('--current', dest='current_app', action='store_true',
                                 help='自动检测并使用当前前台运行的应用包名')

    # 显示选项
    display_group = parser.add_argument_group('显示选项', '控制日志的显示格式和样式')
    display_group.add_argument('-w', '--tag-width', metavar='N', dest='tag_width', type=int, default=23,
                              help='Tag 显示的宽度(字符数)，默认: 23')
    display_group.add_argument('--color-gc', dest='color_gc', action='store_true',
                              help='为垃圾回收(GC)日志添加颜色高亮')
    display_group.add_argument('-c', '--clear', dest='clear_logcat', action='store_true',
                              help='在开始前清空整个 logcat 缓冲区')

    # help
    if len(argv) == 2 and argv[1] == 'help':
        exit()

    args = parser.parse_args()

    file_paths = []
    candidate_path = args.package_or_path
    for path in candidate_path:
        if is_path(path):
            file_paths.append(path)

    if file_paths:
        if args.yml is None:
            print("")
            print_exit("Please using '-y=conf-name' to provide config file to parse this log file.")
            print("The config file is very very simple! More detail about config file please move to : https://github.com/Jacksgong/okcat")
            print("")
            print("-------------------------------------------------------")
            exit()

        parser = LogFileParser(file_paths, args.hide_same_tags)
        parser.setup(args.yml, line_keywords=args.keyword)
        parser.process()
    else:
        is_interrupt_by_user = False

        _adb = Adb()
        _adb.setup(args)
        try:
            _adb.loop()
        except KeyboardInterrupt:
            is_interrupt_by_user = True

        if not is_interrupt_by_user:
            print_warn('ADB CONNECTION IS LOST.')
