#!/usr/bin/env python
# -*- coding: utf-8 -*-

""" APIs for searching access control functions """

import re
from const import *
import os

p = re.compile(r"^\s*(?:(?:inline|static)\s+){0,2}(?!else|typedef|return)\w+\s+\*?\s*[\w\s]+\s*\(")

def search_acfuns(file_path="./kernel/linux/fs/namei.c"):
    idx = 1
    func_map = {}
    curr_declare = ""

    try:
        with open(file_path, "r") as f:
            for line in f:
                m = p.search(line)

                if m is not None:
                    sig = m.group().strip()
                    curr_declare = sig.split("(")[0].split(" ")[-1]
                    
                    if len(curr_declare) > 0 and curr_declare[0] == "*":
                        curr_declare = curr_declare[1:]
                elif "SYSCALL_DEFINE" in line:
                    curr_declare = "sys_" + line.split("(")[1].split(",")[0]

                func_map[idx] = curr_declare

                if line == "}\n":
                    curr_declare = ""

                idx += 1
    except Exception:
        print("fail to open the file")
        return set()

    idx = 1
    kfp_set = set()
    try:
        with open(file_path, "r", encoding="latin-1") as f:
            for line in f:
                if any(word in line for word in get_word_lst()) and len(func_map[idx]) > 0:
                    #print(line)
                    kfp = file_path + ":" + func_map[idx]
                    kfp_set.add(kfp)
                idx += 1
    except Exception:
        pass

    return kfp_set


def search_acfuns_by_keyword(file_path, keyword):
    idx = 1
    func_map = {}
    curr_declare = ""

    with open(file_path, "r", encoding="latin-1") as f: # encoding: kernel source uses ACSII, here we use compatiable latin-1
        for line in f:
            m = p.search(line)

            if m is not None:
                sig = m.group().strip()

                # print(sig)
                curr_declare = sig.split("(")[0].split(" ")[-1]
                if len(curr_declare) > 0 and curr_declare[0] == "*":
                    curr_declare = curr_declare[1:]
            elif "SYSCALL_DEFINE" in line:
                # print(line)

                parts = line.split("(")
                if len(parts) > 1:
                    curr_declare = "sys_" + parts[1].split(",")[0]

            func_map[idx] = curr_declare

            if line == "}\n":
                curr_declare = ""

            idx += 1
    
    idx = 1
    kfp_set = set()
    
    with open(file_path, "r", encoding="latin-1") as f:
        for line in f:
            if len(func_map[idx]) > 0:
                if func_map[idx][0] == "*":
                    func_map[idx] = func_map[idx][1:]

                kfp = file_path + ":" + func_map[idx]
                if keyword is None or keyword in line:
                    kfp_set.add(kfp)
           
            idx += 1
    return kfp_set