<commit_before>//
//  Spec.swift
//  XcodeGen
//
//  Created by <NAME> on 19/5/17.
//
//

import Foundation
import xcproj
import JSONUtilities
import PathKit
import Yams

public struct ProjectSpec {

    public var name: String
    public var targets: [Target]
    public var settings: Settings
    public var settingGroups: [String: Settings]
    public var configs: [Config]
    public var schemes: [Scheme]
    public var options: Options
    public var attributes: [String: Any]
    public var fileGroups: [String]
    public var configFiles: [String: String]
    public var include: [String] = []

    public struct Options {
        public var carthageBuildPath: String?
        public var bundleIdPrefix: String?
        public var settingPresets: SettingPresets = .all
        
        public enum SettingPresets: String {
            case all
            case none
            case project
            case targets
            
            public var applyTarget: Bool {
                switch self {
                case .all, .targets: return true
                default: return false
                }
            }
            
            public var applyProject: Bool {
                switch self {
                case .all, .project: return true
                default: return false
                }
            }
        }

        public init() {
        }
    }

    public init(name: String, configs: [Config] = [], targets: [Target] = [], settings: Settings = .empty, settingGroups: [String: Settings] = [:], schemes: [Scheme] = [], options: Options = Options(), fileGroups: [String] = [], configFiles: [String: String] = [:], attributes: [String: Any] = [:]) {
        self.name = name
        self.targets = targets
        self.configs = configs
        self.settings = settings
        self.settingGroups = settingGroups
        self.schemes = schemes
        self.options = options
        self.fileGroups = fileGroups
        self.configFiles = configFiles
        self.attributes = attributes
    }

    public func getTarget(_ targetName: String) -> Target? {
        return targets.first { $0.name == targetName }
    }

    public func getConfig(_ configName: String) -> Config? {
        return configs.first { $0.name == configName }
    }
}

extension ProjectSpec: CustomDebugStringConvertible {

    public var debugDescription: String {
        var string = "Name: \(name)"
        let indent = "  "
        if !include.isEmpty {
            string += "\nInclude:\n\(indent)" + include.map { "📄  \($0)" }.joined(separator: "\n\(indent)")
        }

        if !settingGroups.isEmpty {
            string += "\nSetting Groups:\n\(indent)" + settingGroups.keys.sorted().map { "⚙️  \($0)" }.joined(separator: "\n\(indent)")
        }

        if !targets.isEmpty {
            string += "\nTargets:\n\(indent)" + targets.map { $0.description }.joined(separator: "\n\(indent)")
        }

        return string
    }
}

extension ProjectSpec: Equatable {

    public static func ==(lhs: ProjectSpec, rhs: ProjectSpec) -> Bool {
        return lhs.name == rhs.name &&
            lhs.targets == rhs.targets &&
            lhs.settings == rhs.settings &&
            lhs.settingGroups == rhs.settingGroups &&
            lhs.configs == rhs.configs &&
            lhs.schemes == rhs.schemes &&
            lhs.fileGroups == rhs.fileGroups &&
            lhs.configFiles == rhs.configFiles &&
            lhs.options == rhs.options &&
            NSDictionary(dictionary: lhs.attributes).isEqual(to: rhs.attributes)
    }
}

extension ProjectSpec.Options: Equatable {

    public static func ==(lhs: ProjectSpec.Options, rhs: ProjectSpec.Options) -> Bool {
        return lhs.carthageBuildPath == rhs.carthageBuildPath &&
            lhs.bundleIdPrefix == rhs.bundleIdPrefix
    }
}

extension ProjectSpec: JSONObjectConvertible {

    public init(jsonDictionary: JSONDictionary) throws {
        let jsonDictionary = try ProjectSpec.filterJSON(jsonDictionary: jsonDictionary)<commit_msg>update equatable<commit_after>//
//  Spec.swift
//  XcodeGen
//
//  Created by <NAME> on 19/5/17.
//
//

import Foundation
import xcproj
import JSONUtilities
import PathKit
import Yams

public struct ProjectSpec {

    public var name: String
    public var targets: [Target]
    public var settings: Settings
    public var settingGroups: [String: Settings]
    public var configs: [Config]
    public var schemes: [Scheme]
    public var options: Options
    public var attributes: [String: Any]
    public var fileGroups: [String]
    public var configFiles: [String: String]
    public var include: [String] = []

    public struct Options {
        public var carthageBuildPath: String?
        public var bundleIdPrefix: String?
        public var settingPresets: SettingPresets = .all
        
        public enum SettingPresets: String {
            case all
            case none
            case project
            case targets
            
            public var applyTarget: Bool {
                switch self {
                case .all, .targets: return true
                default: return false
                }
            }
            
            public var applyProject: Bool {
                switch self {
                case .all, .project: return true
                default: return false
                }
            }
        }

        public init() {
        }
    }

    public init(name: String, configs: [Config] = [], targets: [Target] = [], settings: Settings = .empty, settingGroups: [String: Settings] = [:], schemes: [Scheme] = [], options: Options = Options(), fileGroups: [String] = [], configFiles: [String: String] = [:], attributes: [String: Any] = [:]) {
        self.name = name
        self.targets = targets
        self.configs = configs
        self.settings = settings
        self.settingGroups = settingGroups
        self.schemes = schemes
        self.options = options
        self.fileGroups = fileGroups
        self.configFiles = configFiles
        self.attributes = attributes
    }

    public func getTarget(_ targetName: String) -> Target? {
        return targets.first { $0.name == targetName }
    }

    public func getConfig(_ configName: String) -> Config? {
        return configs.first { $0.name == configName }
    }
}

extension ProjectSpec: CustomDebugStringConvertible {

    public var debugDescription: String {
        var string = "Name: \(name)"
        let indent = "  "
        if !include.isEmpty {
            string += "\nInclude:\n\(indent)" + include.map { "📄  \($0)" }.joined(separator: "\n\(indent)")
        }

        if !settingGroups.isEmpty {
            string += "\nSetting Groups:\n\(indent)" + settingGroups.keys.sorted().map { "⚙️  \($0)" }.joined(separator: "\n\(indent)")
        }

        if !targets.isEmpty {
            string += "\nTargets:\n\(indent)" + targets.map { $0.description }.joined(separator: "\n\(indent)")
        }

        return string
    }
}

extension ProjectSpec: Equatable {

    public static func ==(lhs: ProjectSpec, rhs: ProjectSpec) -> Bool {
        return lhs.name == rhs.name &&
            lhs.targets == rhs.targets &&
            lhs.settings == rhs.settings &&
            lhs.settingGroups == rhs.settingGroups &&
            lhs.configs == rhs.configs &&
            lhs.schemes == rhs.schemes &&
            lhs.fileGroups == rhs.fileGroups &&
            lhs.configFiles == rhs.configFiles &&
            lhs.options == rhs.options &&
            NSDictionary(dictionary: lhs.attributes).isEqual(to: rhs.attributes)
    }
}

extension ProjectSpec.Options: Equatable {

    public static func ==(lhs: ProjectSpec.Options, rhs: ProjectSpec.Options) -> Bool {
        return lhs.carthageBuildPath == rhs.carthageBuildPath &&
            lhs.bundleIdPrefix == rhs.bundleIdPrefix &&
            lhs.settingPresets == rhs.settingPresets
    }
}

extension ProjectSpec: JSONObjectConvertible {

    public init(jsonDictionary: JSONDictionary) throws {
        let jsonDictionary = try ProjectSpec.filterJSON(jsonDictionary: jsonDictionary)
{'fraction_non_alphanumeric': 0.11159116158498951, 'fraction_numerical': 0.002468831008517467, 'mean_word_length': 2.0712661106899164, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, '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': '508392', 'n_tokens_mistral': 2248, 'n_tokens_neox': 2158, 'n_words': 592}