#!/usr/bin/env python3
#
# Copyright (C) 2020-2021 Savoir-faire Linux Inc.
#
# Author: Aline Gondim Santos <aline.gondimsantos@savoirfairelinux.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# Creates packaging targets for a distribution and architecture.
# This helps reduce the length of the top Makefile.
#

from userProfile import UserInfos
from sdkConstants import *
import os
import json
import shutil
from termcolor import colored, cprint


class PluginStructure(UserInfos):
    def __init__(self, action):
        UserInfos.__init__(self, action)
        self.create(action)
        self.createFolderStructure()

    def delete(self):
        if (os.path.exists(self.pluginDirectory)
                and os.path.isdir(self.pluginDirectory)):
            shutil.rmtree(self.pluginDirectory)

    def reInitialize(self, pluginName):
        self.pluginName = pluginName
        self.pluginDirectory = f"./../{self.pluginName}"
        self.manifestFile = f"{self.pluginDirectory}/manifest.json"
        self.pluginDataDirectory = f"{self.pluginDirectory}/data"
        self.pluginIcon = f"{self.pluginDataDirectory}/icon.svg"
        self.preferencesFile = f"{self.pluginDataDirectory}/preferences.json"
        self.packageFile = f"{self.pluginDirectory}/package.json"
        self.cmakelistsFile = f"{self.pluginDirectory}/CMakeLists.txt"
        self.buildFile = f"{self.pluginDirectory}/build.sh"

    def create(self, action):
        plugins = os.listdir("../")
        print(colored("\nLeave Empty or Press 'q' to quit this option.", "yellow"))
        if (action == ACTIONS["CREATE"]):
            print("\nNow, you need to tell how you want yout plugin to be called.")
            pluginName = "SDK"
            while (pluginName in plugins):
                pluginName = input("\nChoose a cool name for your plugin: ")
                if (pluginName == 'q' or not pluginName):
                    self.reInitialize('')
                    break
                if (pluginName in plugins):
                    print(colored("This name is invalid!", "red"))
                else:
                    self.reInitialize(pattern.sub('', pluginName))
            if (self.pluginName):
                coloredTitle = colored(self.pluginName, "green")
                print(f"\nNice! Your {coloredTitle} will be awesome!")

        elif (action == ACTIONS["DELETE"] or action == ACTIONS["DELETE_PREFERENCES"] \
                or action == ACTIONS["DELETE_MANIFEST"]):
            pluginName = ""
            while (pluginName not in plugins or pluginName in FORBIDDEN_NAMES):
                pluginName = input("\nPlugin to be modified: ")
                if (pluginName == 'q' or not pluginName):
                    self.reInitialize('')
                    break
                if (pluginName not in plugins or pluginName in FORBIDDEN_NAMES):
                    print(colored("This name is invalid!", "red"))
                else:
                    self.reInitialize(pattern.sub('', pluginName))

        elif (action == ACTIONS["CREATE/MODIFY_MANIFEST"] or action == ACTIONS["CREATE_PREFERENCES"] \
                or action == ACTIONS["CREATE_FUNCTIONALITY"] or action == ACTIONS["CREATE_PACKAGE_JSON"] \
                or action == ACTIONS["CREATE_MAIN"] or action == ACTIONS["CREATE_BUILD_FILES"] \
                or action == ACTIONS["ASSEMBLE"] or action == ACTIONS["PREASSEMBLE"] \
                or action == ACTIONS["BUILD"]):
            pluginName = ""
            while (pluginName in FORBIDDEN_NAMES):
                pluginName = input("\nPlugin to be modified or created: ")
                if (pluginName == 'q' or not pluginName):
                    self.reInitialize('')
                    break
                if (pluginName in FORBIDDEN_NAMES):
                    print(colored("This name is invalid!", "red"))
                else:
                    self.reInitialize(pattern.sub('', pluginName))

    def createFolderStructure(self):
        if (self.pluginName):
            if (not os.path.exists(self.pluginDirectory)):
                os.mkdir(self.pluginDirectory)
            if (not os.path.exists(self.pluginDataDirectory)):
                os.mkdir(self.pluginDataDirectory)
            if (not os.path.exists(self.pluginIcon)):
                shutil.copyfile("./Templates/icon.svg", self.pluginIcon)

    def saveManifest(self, manifestTxt):
        with open(self.manifestFile, 'w') as f:
            json.dump(manifestTxt, f, indent=4)
            f.close()

    def deleteManifest(self):
        if (os.path.exists(self.manifestFile)):
            os.remove(self.manifestFile)

    def isManifest(self):
        return os.path.exists(self.manifestFile)

    def isMainDirectory(self):
        return os.path.exists(self.pluginDirectory)
