from django.shortcuts import render
from django.core.files.storage import FileSystemStorage
from rest_framework.parsers import FileUploadParser
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework import status

from .serializers import FileSerializer
from tugas.forms import uploadForm

import pandas as pd
import numpy as np
from androguard import misc
# import tensorflow as tf
from joblib import dump
from joblib import load
# import keras
# from keras.models import load_model


# Create your views here.
def index(request):
    return render(request, 'index.html')

def result(request):
    if request.method == 'POST':
        form = uploadForm(request.POST, request.FILES)

        if form.is_valid():
            file_input = request.FILES['file_input']
            fs = FileSystemStorage()
            file = fs.save('test.apk', file_input)

            # Extract APK File
            listOfInputApkPermission = [['Normal', 'Signature', 'Dangerous']]
            a, d, dx = misc.AnalyzeAPK(fs.path(file))
            app_name = a.get_app_name()
            input_apk_permission = a.get_permissions()
            listOfInputApkPermission.append((a.get_app_name(), ','.join(input_apk_permission)))
            headers = listOfInputApkPermission.pop(0)
            df = pd.DataFrame(listOfInputApkPermission, columns=headers)

            # Get and Check Permission
            data_test_detected = getTrainAndTestDataset(df)
            permission = df['Permission']

            # Prepare Data for test
            data_test_detected = data_test_detected.astype('float32')
            data_test_detected = np.array(data_test_detected)
            data_test_detected = data_test_detected.reshape(data_test_detected.shape[0], 13, 13, 1)

            # Test Data
            load_model = tf.keras.models.load_model(fs.path('model_TA_03.h5'))
            result = load_model.predict_classes(data_test_detected)
            if result == 0:
                status = "Kurang Berbahaya"
            elif result == 1:
                status = "Berbahaya"
            else:
                status = "Tidak Berbahaya"

            fs.delete(file)
            return render(request, 'result.html', {'app_name': app_name,
                                                   'status': status,
                                                   'permission': permission,
                                                   })

    return render(request, 'result.html')


def extract(file):
    fs = FileSystemStorage()
    android_manifest_permission = pd.read_csv(fs.path('manifestPermissionAndroid.csv'))
    android_manifest_permission['class'] = 'Miscellaneous'
    android_groups_permission = pd.read_csv(fs.path('permissionGeneral.csv'))
    android_general_permission = android_groups_permission.append(android_manifest_permission).drop_duplicates(
        subset='name').reset_index(drop=True)
    normal_permission = android_general_permission.loc[android_general_permission['class'] == 'Normal']
    signature_permission = android_general_permission.loc[android_general_permission['class'] == 'Signature']
    dangerous_permission = android_general_permission.loc[android_general_permission['class'] == 'Dangerous']
    dataResult = pd.DataFrame(columns=['Normal', 'Signature', 'Dangerous'])

    a, d, dx = misc.AnalyzeAPK(file)
    appname = a.get_app_name()
    input_apk_permission = a.get_permissions()
    listOfInputApkPermission = [['File Name', 'Permission']]
    listOfInputApkPermission.append((appname, ','.join(input_apk_permission)))
    headers = listOfInputApkPermission.pop(0)
    dfData = pd.DataFrame(listOfInputApkPermission, columns=headers)
    detected = dfData.fillna('')
    zeroDataframe = pd.DataFrame({0: 0}, index=[0])
    for index, row in detected.iterrows():
        tempData = pd.DataFrame()
        dfAPKPermission = pd.DataFrame(row[2].split(sep=','))
        dfAPKPermission.columns = ['name']
        # APK Name
        tempData = tempData.append(row.to_frame().transpose().APK.reset_index(drop=True))
        # Normal
        normal_counter = normal_permission.name.isin(dfAPKPermission.name).to_frame().name.value_counts().to_frame()
        normal_counter = normal_counter.drop([False]).reset_index(drop=True)
        normal_counter.columns = [0]
        if normal_counter.empty:
            normal_counter = zeroDataframe
        # Signature
        signature_counter = signature_permission.name.isin(
            dfAPKPermission.name).to_frame().name.value_counts().to_frame()
        signature_counter = signature_counter.drop([False]).reset_index(drop=True)
        signature_counter.columns = [0]
        if signature_counter.empty:
            signature_counter = zeroDataframe

        # Dangerous
        dangerous_counter = dangerous_permission.name.isin(
            dfAPKPermission.name).to_frame().name.value_counts().to_frame()
        dangerous_counter = dangerous_counter.drop([False]).reset_index(drop=True)
        dangerous_counter.columns = [0]
        if dangerous_counter.empty:
            dangerous_counter = zeroDataframe

        tempData = tempData.append(normal_counter). \
            append(signature_counter). \
            append(dangerous_counter).transpose()
        tempData.columns = ['Normal', 'Signature', 'Dangerous']
        dataResult = dataResult.append(tempData)

    return dataResult



class FileUploadView(APIView):
    parser_class = (FileUploadParser,)

    def post(self, request, *args, **kwargs):

        file_serializer = FileSerializer(data=request.data)
        if file_serializer.is_valid():
            # get the apk
            file_input = request.data['file']
            fs = FileSystemStorage()
            file = fs.save('test.apk', file_input)

            # Extract APK File
            df = extract(file)

            X = df[1:,:3]
            # Get and Check Permission
            # data_test_detected = getTrainAndTestDataset(df)
            # permission = df['Permission']

            # Prepare Data for test
            # data_test_detected = data_test_detected.astype('float32')
            # data_test_detected = np.array(data_test_detected)
            # data_test_detected = data_test_detected.reshape(data_test_detected.shape[0], 13, 13, 1)

            # Test Data
            load_model = load(fs.path('model_TA_03.h5'))
            y_pred = load_model.predict(X)
            result = [round(value) for value in y_pred]

            if result != 0:
                statuss = "Berbahaya"
            else:
                statuss = "Tidak Berbahaya"

            fs.delete(file)

            result = {
                        'status': status,
                        'malware_name': result,
                    }

            return Response(result, status=status.HTTP_201_CREATED)
        else:
            return Response(file_serializer.errors, status=status.HTTP_400_BAD_REQUEST)


# Function
def getTrainAndTestDataset(dfData):
    fs = FileSystemStorage()
    android_manifest_permission = pd.read_csv(fs.path('manifestPermissionAndroid.csv'))
    android_manifest_permission['class'] = 'Miscellaneous'
    android_groups_permission = pd.read_csv(fs.path('permissionGeneral.csv'))
    android_general_permission = android_groups_permission.append(android_manifest_permission).drop_duplicates(subset='name').reset_index(drop=True)
    normal_permission = android_general_permission.loc[android_general_permission['class'] == 'Normal']
    signature_permission = android_general_permission.loc[android_general_permission['class'] == 'Signature']
    dangerous_permission = android_general_permission.loc[android_general_permission['class'] == 'Dangerous']

    dfPermission = android_groups_permission.append(android_manifest_permission).drop_duplicates(
        subset='name').reset_index(drop=True)
    addNineRow = pd.DataFrame([[0], [0], [0], [0], [0], [0], [0], [0], [0]])
    addNineRow.columns = ['status']
    counter = 0
    data = dfData['Permission']
    data = data.fillna('')
    dataResult = pd.DataFrame()

    for row in data:
        dfAPKPermission = row.split(sep=',')
        dfAPKPermission = pd.DataFrame(dfAPKPermission)
        dfAPKPermission.columns = ['name']
        dfAPKPermission = dfPermission.name.isin(dfAPKPermission.name).astype(int).to_frame()
        dfAPKPermission.columns = ['status']
        dfAPKPermission = dfAPKPermission.append(addNineRow).reset_index(drop=True)
        dfAPKPermission = dfAPKPermission.transpose()
        dataResult = dataResult.append(dfAPKPermission)

    dataResult = dataResult.replace(1, 255).reset_index(drop=True)
    return dataResult