 import Foundation
 import SourceKittenFramework
 
-public struct UnusedControlFlowLabelRule: ASTRule, ConfigurationProviderRule, AutomaticTestableRule, CorrectableRule {
+public struct UnusedControlFlowLabelRule: SubstitutionCorrectableASTRule, ConfigurationProviderRule,
+                                          AutomaticTestableRule {
     public var configuration = SeverityConfiguration(.warning)
 
     public init() {}

        }
    }

    public func correct(file: File) -> [Correction] {
        let violatingRanges = file.ruleEnabled(violatingRanges: violationRanges(in: file), for: self)
        guard !violatingRanges.isEmpty else { return [] }

        let description = type(of: self).description
        var corrections = [Correction]()
        var contents = file.contents
        for range in violatingRanges {
            var rangeToRemove = range
            let contentsNSString = contents.bridge()
            if let byteRange = contentsNSString.NSRangeToByteRange(start: range.location, length: range.length),
                let nextToken = file.syntaxMap.tokens.first(where: { $0.offset > byteRange.location }),
                let nextTokenLocation = contentsNSString.byteRangeToNSRange(start: nextToken.offset, length: 0) {
                rangeToRemove.length = nextTokenLocation.location - range.location
            }

            contents = contentsNSString.replacingCharacters(in: rangeToRemove, with: "")
            let location = Location(file: file, characterOffset: range.location)
            corrections.append(Correction(ruleDescription: description, location: location))
        }

        file.write(contents)
        return corrections
    }

    private func violationRanges(in file: File, kind: StatementKind,
                                 dictionary: [String: SourceKitRepresentable]) -> [NSRange] {
        guard type(of: self).kinds.contains(kind),
            let offset = dictionary.offset, let length = dictionary.length,
            case let byteRange = NSRange(location: offset, length: length),
            case let tokens = file.syntaxMap.tokens(inByteRange: byteRange),
            let firstToken = tokens.first,
            SyntaxKind(rawValue: firstToken.type) == .identifier,
            case let contents = file.contents.bridge(),
            let tokenContent = contents.substring(with: firstToken),
            let range = contents.byteRangeToNSRange(start: offset, length: length) else {
                return []
        }


        return [violationRange]
    }
}
