<commit_before>//
//  mainFunctions.swift
//
//  Created by <NAME> on 14/05/2016.
//  Copyright © 2016 <NAME>
//  Released under an MIT license: http://opensource.org/licenses/MIT
//

import Foundation
import RegexReplacer
import FoundationExtensions

protocol LocalizationStore {
    func storeFormattedLocalizable(data: Data) throws
    func storeFormattedStringsDict(data: Data) throws
}

struct FileLocalizationStore: LocalizationStore {
    private let localizablePath: String
    private let stringsDictPath: String

    init(outputFolderPath: String) {
        localizablePath = outputFolderPath.appending(pathComponent: "Localizable.strings")
        stringsDictPath = outputFolderPath.appending(pathComponent: "Localizable.stringsdict")
    }

    func storeFormattedLocalizable(data: Data) throws {
        try write(data: data, toFilePath: localizablePath)
    }

    func storeFormattedStringsDict(data: Data) throws {
        try write(data: data, toFilePath: stringsDictPath)
    }

    private func write(data: Data, toFilePath filePath: String) throws {
        guard FileManager().createFile(atPath: filePath, contents: data, attributes: nil) else {
            throw Error.fileWriteError(path: filePath)
        }
    }

    enum Error: Swift.Error {
        case fileWriteError(path: String)
    }
}

protocol StringContentProvider {
    func content() throws -> String
}

struct StringFileContentProvider: StringContentProvider {
    let filePath: String
    let encoding: String.Encoding

    init(filePath: String, encoding: String.Encoding = .utf16) {
        self.filePath = filePath
        self.encoding = encoding
    }

    func content() throws -> String {
        return try readFile(atPath: filePath, encoding: encoding)
    }

    private func readFile(atPath path: String, encoding: String.Encoding) throws -> String {
        let fileManager = FileManager()
        guard let content = fileManager.contents(atPath: path) else {
            throw Error.fileNotFound(path: path)
        }
        guard let contentAsString = String(data: content, encoding: encoding) else {
            throw Error.invalidFileContent(path: path, data: content)
        }
        return contentAsString
    }

    enum Error: Swift.Error {
        case fileNotFound(path: String)
        case invalidFileContent(path: String, data: Data)
    }
}

public func convert(androidFileName fileName: String, outputPath: String, includePlurals: Bool) -> Bool {
    let stringsFileProvider: StringContentProvider = StringFileContentProvider(filePath: fileName, encoding: .utf8)
    let store: LocalizationStore = FileLocalizationStore(outputFolderPath: outputPath)

    do {
        let androidLocalizationString = try stringsFileProvider.content()
        let localization = try AndroidStringsParser().parse(string: androidLocalizationString)
        let localizableString = try LocalizableFormatter(includePlurals: includePlurals).format(localization)
        try store.storeFormattedLocalizable(data: localizableString)
        let stringsDictContent = try StringsDictFormatter().format(localization)
        try store.storeFormattedStringsDict(data: stringsDictContent)
    } catch StringsDictFormatter.Error.noPlurals {
        print("No plural found, skipping stringsdict file.")
    } catch {
        print("Error: \(error)")
        return false
    }

    return true
}

func readFile(withName fileName: String, encoding: String.Encoding = String.Encoding.utf16) -> String? {
    let fileManager = FileManager()
    let filePath: String
    if fileManager.fileExists(atPath: fileName) {
        filePath = fileName
    } else {
        filePath = NSString.path(withComponents: [fileManager.currentDirectoryPath, fileName])
    }
    guard let content = fileManager.contents(atPath: filePath) else {
        print("Failed to load file \(fileName) from path \(filePath)")
        return nil
    }
    guard let contentAsString = String(data: content, encoding: encoding) else {
        print("Failed to read contents of file at path \(filePath)")
        return nil
    }
    return contentAsString
}

func write(stringData string: String, toFilePath filePath: String) -> Bool {
    if !FileManager().createFile(atPath: filePath, contents: string.data(using: String.Encoding.utf8), attributes: nil) {
        print("Failed to write output at path: \(filePath)")
        return false
    }
    return true
}

public func convert(androidFolder resourceFolder: String, outputPath: String, includePlurals: Bool) -> Bool {
    let fileManager = FileManager()

    let outputFolder = outputPath

    do {
        let folders = try fileManager.contentsOfDirectory(atPath: resourceFolder)
        let valuesFolders = folders.filter { (folderName) -> Bool in
            return folderName.hasPrefix("values")
        }

        let results = try valuesFolders.map { (valuesFolderName) -> Bool in
            guard let outputFolderName = iOSFolderName(from: valuesFolderName) else {
                print("Could not convert values folder name '\(valuesFolderName)' to its iOS counterpart")
                return false
            }
            let outputFolderPath = outputFolder.appending(pathComponent: outputFolderName)
            try fileManager.createDirectory(atPath: outputFolderPath, withIntermediateDirectories: true, attributes: nil)
            let inputFilePath = resourceFolder
                .appending(pathComponent: valuesFolderName)
                .appending(pathComponent: "strings.xml")
            return convert(androidFileName: inputFilePath, outputPath: outputFolderPath, includePlurals: includePlurals)
        }
        return results.reduce(true, { (accumulator, result) -> Bool in
            return accumulator && result
        })
    } catch {<commit_msg>Remove unused readFile and write functions<commit_after>//
//  mainFunctions.swift
//
//  Created by <NAME> on 14/05/2016.
//  Copyright © 2016 <NAME>
//  Released under an MIT license: http://opensource.org/licenses/MIT
//

import Foundation
import RegexReplacer
import FoundationExtensions

protocol LocalizationStore {
    func storeFormattedLocalizable(data: Data) throws
    func storeFormattedStringsDict(data: Data) throws
}

struct FileLocalizationStore: LocalizationStore {
    private let localizablePath: String
    private let stringsDictPath: String

    init(outputFolderPath: String) {
        localizablePath = outputFolderPath.appending(pathComponent: "Localizable.strings")
        stringsDictPath = outputFolderPath.appending(pathComponent: "Localizable.stringsdict")
    }

    func storeFormattedLocalizable(data: Data) throws {
        try write(data: data, toFilePath: localizablePath)
    }

    func storeFormattedStringsDict(data: Data) throws {
        try write(data: data, toFilePath: stringsDictPath)
    }

    private func write(data: Data, toFilePath filePath: String) throws {
        guard FileManager().createFile(atPath: filePath, contents: data, attributes: nil) else {
            throw Error.fileWriteError(path: filePath)
        }
    }

    enum Error: Swift.Error {
        case fileWriteError(path: String)
    }
}

protocol StringContentProvider {
    func content() throws -> String
}

struct StringFileContentProvider: StringContentProvider {
    let filePath: String
    let encoding: String.Encoding

    init(filePath: String, encoding: String.Encoding = .utf16) {
        self.filePath = filePath
        self.encoding = encoding
    }

    func content() throws -> String {
        return try readFile(atPath: filePath, encoding: encoding)
    }

    private func readFile(atPath path: String, encoding: String.Encoding) throws -> String {
        let fileManager = FileManager()
        guard let content = fileManager.contents(atPath: path) else {
            throw Error.fileNotFound(path: path)
        }
        guard let contentAsString = String(data: content, encoding: encoding) else {
            throw Error.invalidFileContent(path: path, data: content)
        }
        return contentAsString
    }

    enum Error: Swift.Error {
        case fileNotFound(path: String)
        case invalidFileContent(path: String, data: Data)
    }
}

public func convert(androidFileName fileName: String, outputPath: String, includePlurals: Bool) -> Bool {
    let stringsFileProvider: StringContentProvider = StringFileContentProvider(filePath: fileName, encoding: .utf8)
    let store: LocalizationStore = FileLocalizationStore(outputFolderPath: outputPath)

    do {
        let androidLocalizationString = try stringsFileProvider.content()
        let localization = try AndroidStringsParser().parse(string: androidLocalizationString)
        let localizableString = try LocalizableFormatter(includePlurals: includePlurals).format(localization)
        try store.storeFormattedLocalizable(data: localizableString)
        let stringsDictContent = try StringsDictFormatter().format(localization)
        try store.storeFormattedStringsDict(data: stringsDictContent)
    } catch StringsDictFormatter.Error.noPlurals {
        print("No plural found, skipping stringsdict file.")
    } catch {
        print("Error: \(error)")
        return false
    }

    return true
}

public func convert(androidFolder resourceFolder: String, outputPath: String, includePlurals: Bool) -> Bool {
    let fileManager = FileManager()

    let outputFolder = outputPath

    do {
        let folders = try fileManager.contentsOfDirectory(atPath: resourceFolder)
        let valuesFolders = folders.filter { (folderName) -> Bool in
            return folderName.hasPrefix("values")
        }

        let results = try valuesFolders.map { (valuesFolderName) -> Bool in
            guard let outputFolderName = iOSFolderName(from: valuesFolderName) else {
                print("Could not convert values folder name '\(valuesFolderName)' to its iOS counterpart")
                return false
            }
            let outputFolderPath = outputFolder.appending(pathComponent: outputFolderName)
            try fileManager.createDirectory(atPath: outputFolderPath, withIntermediateDirectories: true, attributes: nil)
            let inputFilePath = resourceFolder
                .appending(pathComponent: valuesFolderName)
                .appending(pathComponent: "strings.xml")
            return convert(androidFileName: inputFilePath, outputPath: outputFolderPath, includePlurals: includePlurals)
        }
        return results.reduce(true, { (accumulator, result) -> Bool in
            return accumulator && result
        })
    } catch {
{'fraction_non_alphanumeric': 0.08263993948562784, 'fraction_numerical': 0.0031202723146747354, 'mean_word_length': 3.2324929971988796, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1078942', 'n_tokens_mistral': 2766, 'n_tokens_neox': 2681, 'n_words': 751}