#!/usr/bin/env python3
# coding: utf-8

# Copyright (c) 2020 Huawei Technologies Co., Ltd.
# oec-hardware is licensed under the Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
#     http://license.coscl.org.cn/MulanPSL2
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
# PURPOSE.
# See the Mulan PSL v2 for more details.
# Create: 2020-04-01

"""Operation of client """

import os
import sys
import fcntl
import argparse
import traceback
import configparser

sys.path.append("/usr/share/kylinch/lib/")
os.putenv("PYTHONPATH", "/usr/share/kylinch/lib/")

from compatible.compatibility import Certification
from compatible.devicecompatibility import DeviceCertification
import compatible.version
from compatible.test import Test
from compatible.env import CertEnv


class CertLock:
    """
    certlock
    """

    def __init__(self, filename):
        self.filename = filename
        self.fd_obj = open(filename, 'w')

    def acquire(self):
        """
        acquire
        """
        try:
            # 对文件加锁fcntl.LOCK_EX  排他锁 fcntl.LOCK_NB 非阻塞锁
            fcntl.flock(self.fd_obj, fcntl.LOCK_EX | fcntl.LOCK_NB)
            return True
        except IOError:
            return False

    def release(self):
        """
        release
        """
        # 对文件解锁
        fcntl.flock(self.fd_obj, fcntl.LOCK_UN)

    def __del__(self):
        self.fd_obj.close()


if __name__ == '__main__':
    if os.getuid() > 0:
        sys.stderr.write("You need to be root to run this program.\n")
        sys.exit(1)

    parser = argparse.ArgumentParser(description="Run Kylin Hardware Compatibility Test Suite")
    parser.add_argument('--clean', action='store_true', help='Clean saved testsuite.')
    parser.add_argument('--rebootup', action='store_true', help='Continue run testsuite after reboot system.')
    parser.add_argument('--version', action='store_true', help='Show testsuite version.')
    parser.add_argument('--auth', action='store', dest='auth_path', help='授权认证, --auth <认证文件路径>')
    parser.add_argument('--device', action='store_true', help='部件用例测试')
    parser.add_argument('--debug', action='store_true', help='debug调试')
    parser.add_argument('--resetserverip', action='store_true', help='设置server端ip')
    args = parser.parse_args()

    # 添加锁文件
    lock = CertLock("/var/lock/kylinch.lock")
    # 加锁不成功（程序已运行了）
    if not lock.acquire():
        sys.stderr.write("The kylinch may be running already, you should not run it repeated.\n")
        sys.exit(1)
    config = configparser.ConfigParser()

    try:
        cert = Certification()
        dcert = DeviceCertification()
        test = Test()
        if args.debug:
            config["DEFAULT"] = {
                'debug': 'True'
            }
            with open(CertEnv.debug_conf, 'w') as file:
                config.write(file)
        else:
            config["DEFAULT"] = {
                'debug': ''
            }
            with open(CertEnv.debug_conf, 'w') as file:
                config.write(file)
        if args.clean:
            if not cert.clean():
                lock.release()
                sys.exit(1)
        elif args.resetserverip:
            if not cert.resetserverip():
                lock.release()
                sys.exit(1)
        elif args.rebootup and args.device:
            if not dcert.run_rebootup():
                lock.release()
                sys.exit(1)
        elif args.rebootup:
            if not cert.run_rebootup():
                lock.release()
                sys.exit(1)
        elif args.version:
            print("version: %s" % compatible.version.version)
        elif args.auth_path:
            if not cert.authorized(args.auth_path):
                lock.release()
                sys.exit(1)
        elif args.device:
            if not dcert.run():
                lock.release()
                sys.exit(1)
        else:
            if not cert.run():
                lock.release()
                sys.exit(1)

        lock.release()
        sys.exit(0)
    except Exception as e:
        print("[ERROR] %s" % traceback.format_exc())
        lock.release()
        sys.exit(1)
