class SmartlingApi:
    def __init__(self, apiKey, projectId):
        self.file_api = SmartlingFileApiFactory().getSmartlingTranslationApiProd(apiKey, projectId)

    # Upload a source file
    def uploadFile(self, uploadData):
        self.disableStdOut()
        response, code = self.file_api.upload(uploadData)
        self.enableStdOut()
        if code == 200 and response.code == "SUCCESS":
            return response.data
        else:
            raise IOError("Failed to upload ({0}), caused by: {1}".format(code, self._getMessages(response)))

    # Import a translation
    # ApiResponse: {"response":{"data":{"wordCount":10,"translationImportErrors":[{"contentFileId":238103,"stringHashcode":"851194c88c080f24ef257383841eb757","messages":["Information about import key was not found"],"importKey":null}],"stringCount":5},"code":"SUCCESS","messages":[]}}
    def importFile(self, uploadData, locale, overwrite=False):
        self.disableStdOut()
        response, code = self.file_api.import_call(uploadData, locale, translationState="PUBLISHED", overwrite=str(overwrite).lower())
        self.enableStdOut()
        if code == 200 and response.code == "SUCCESS":
            if response.data.translationImportErrors and len(response.data.translationImportErrors) > 0:
                logging.error("Error Importing translation (%s): %s, Caused by:\n%s",
                              locale,
                              uploadData.uriPath + uploadData.name,
                              self._getStringFromArray(response.data.translationImportErrors))
                raise IOError("Failed to import translation file: {0}".format(uploadData.uriPath + uploadData.name))
            return response.data
        else:
            raise IOError("Failed to import ({0}), caused by: {1}".format(code, self._getMessages(response)))

    # Get a translated files
    def getFile(self, fileUri, locale):
        self.disableStdOut()
        data, code = self.file_api.get(fileUri, locale)
        self.enableStdOut()
        if code == 200:
            return data
        else:
            raise IOError("Failed to get file ({0}): {1}".format(locale, fileUri))

    # Get file status
    # ApiResponse: {"response":{"data":{"fileUri":"common.json","wordCount":9,"fileType":"json","callbackUrl":null,"lastUploaded":"2014-10-30T19:09:36","stringCount":5,"approvedStringCount":0,"completedStringCount":0},"code":"SUCCESS","messages":[]}}
    def getStatus(self, fileUri, locale):
        self.disableStdOut()
        response, code = self.file_api.status(fileUri, locale)
        self.enableStdOut()
        if code == 200 and response.code == "SUCCESS":
            return response.data
        else:
            raise IOError("Failed to get file status ({0}): {1}, caused by: {2}".format(locale, fileUri, self._getMessages(response)))

    # Get list of the project locales
    # ApiResponse: [{'locale': 'de-DE', 'translated': 'Deutsch', 'name': 'German (Germany)'}, {'locale': 'pl-PL', 'translated': 'Polski', 'name': 'Polish (Poland)'}]
    def getProjectLocales(self):
        self.disableStdOut()
        response, code = self.file_api.command(ReqMethod.GET, "/v1/project/locale/list", params={})
        self.enableStdOut()
        if code != 200 or response.code != "SUCCESS":
            raise IOError("Failed to get project locales, caused by: {0}".format(self._getMessages(response)))
        return response.data.locales

    def _getMessages(self, response):
        if response and response.messages:
            return self._getStringFromArray(response.messages)

    def _getStringFromArray(self, array):
        message = ""
        for m in array:
            if len(message) > 0:
                message += "\n"
            message += str(m)
        return message

    def disableStdOut(self):
        self._stdout = sys.stdout
        null = open(os.devnull, 'wb')
        sys.stdout = null

    def enableStdOut(self):
        if self._stdout:
            sys.stdout = self._stdout