#!/usr/bin/env python3
#
# Copyright (C) 2020 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.png"
        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.png", 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)
