<commit_before>import RxBluetoothKit
import RxSwift
import RxCocoa
import UIKit

final class CharacteristicsViewController: UIViewController, CustomView {

    typealias ViewClass = BaseView

    typealias CharacteristicsDataSource = TableViewDataSource<CharacteristicsViewModelItem>

    private let viewModel: CharacteristicsViewModelType

    private let dataSource: CharacteristicsDataSource

    private let disposeBag = DisposeBag()

    init(with dataSource: CharacteristicsDataSource, viewModel: CharacteristicsViewModelType) {
        self.dataSource = dataSource
        self.viewModel = viewModel
        super.init(nibName: nil, bundle: nil)
        view.backgroundColor = .white
    }

    @available(*, unavailable)
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func loadView() {
        self.view = ViewClass()
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        setupTableView()
        setDataSourceRefreshBlock()
        bindViewModel()
    }

    private func setupTableView() {
        customView.setTableView(dataSource: dataSource, delegate: self)
        registerCells()
    }

    private func setDataSourceRefreshBlock() {
        self.dataSource.setRefreshBlock { [weak self] in
            self?.customView.refreshTableView()
        }
    }

    private func bindViewModel() {
        subscribeViewModelOutputs()
        dataSource.bindItemsObserver(to: viewModel.characteristicsOutput)
    }

    private func subscribeViewModelOutputs() {
        subscribeDataUpdateOutput()
        subscribeAlertTriggerOutput()
    }

    private func subscribeDataUpdateOutput() {
        viewModel.dataUpdateOutput.subscribe(onNext: { [unowned self]  _ in
            self.customView.refreshTableView()
        }).disposed(by: disposeBag)
    }

    private func subscribeAlertTriggerOutput() {
        viewModel.alertTriggerOutput.subscribe(onNext: { [unowned self] message in
            self.showAlert(title: Constant.Strings.titleSuccess, message: message)
        }).disposed(by: disposeBag)
    }

    private func registerCells() {
        customView.register(cellType: CharacterisiticsTableViewCell.self,
                forCellReuseIdentifier: String(describing: CharacterisiticsTableViewCell.self))
    }

    private func addWriteActions(to actionSheet: UIAlertController) {
        let writeValueNotificationAction = UIAlertAction(title: Constant.Strings.titleWrite,
                style: .default) { _ in
            self.showWriteFieldForCharacteristic()
        }
        actionSheet.addAction(writeValueNotificationAction)
    }

    private func addReadActions(to actionSheet: UIAlertController) {
        let readValueNotificationAction = UIAlertAction(title: Constant.Strings.titleRead,
                style: .default) { [weak self] _ in
            self?.viewModel.triggerValueRead()
        }
        actionSheet.addAction(readValueNotificationAction)
    }

    private func addNotificationActions(to actionSheet: UIAlertController) {
        let turnNotificationOffAction = UIAlertAction(title: Constant.Strings.turnOffNotifications,
                style: .default) { _ in
            self.viewModel.setNotificationsState(enabled: false)
        }
        let turnNotificationOnAction = UIAlertAction(title: Constant.Strings.turnOnNotifications,
                style: .default) { _ in
            self.viewModel.setNotificationsState(enabled: true)
        }
        actionSheet.addAction(turnNotificationOffAction)
        actionSheet.addAction(turnNotificationOnAction)
    }

    private func addDismissAction(to actionSheet: UIAlertController) {
        let dismissAction = UIAlertAction(title: Constant.Strings.titleCancel,
                style: .cancel) { [unowned self] _ in
            self.dismiss(animated: true, completion: nil)
        }
        actionSheet.addAction(dismissAction)
    }

    fileprivate func showWriteFieldForCharacteristic() {
        let valueWriteController = UIAlertController(title: Constant.Strings.titleWriteValue,
                message: Constant.Strings.hexValue,
                preferredStyle: .alert)
        valueWriteController.addTextField { _ in
        }

        valueWriteController.addAction(UIAlertAction(title: Constant.Strings.titleCancel, style: .cancel, handler: nil))
        valueWriteController.addAction(UIAlertAction(title: Constant.Strings.titleWrite, style: .default) { _ in

            if let _text = valueWriteController.textFields?.first?.text {
                self.viewModel.writeValueForCharacteristic(hexadecimalString: _text)
            }

        })
        present(valueWriteController, animated: true, completion: nil)

    }

    private func showAlert(title: String, message: String) {
        let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
        let action = UIAlertAction(title: Constant.Strings.titleOk, style: .default) { [weak self] _ in
            self?.dismiss(animated: true)
        }
        alertController.addAction(action)
        present(alertController, animated: true)
    }
}

extension CharacteristicsViewController: UITableViewDelegate {
    func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
        return 140
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        guard let characteristic = dataSource.takeItemAt(index: indexPath.row) as? Characteristic else {
            return
        }<commit_msg>Removed unnecessary [weak self] in UIAlertController actions<commit_after>import RxBluetoothKit
import RxSwift
import RxCocoa
import UIKit

final class CharacteristicsViewController: UIViewController, CustomView {

    typealias ViewClass = BaseView

    typealias CharacteristicsDataSource = TableViewDataSource<CharacteristicsViewModelItem>

    private let viewModel: CharacteristicsViewModelType

    private let dataSource: CharacteristicsDataSource

    private let disposeBag = DisposeBag()

    init(with dataSource: CharacteristicsDataSource, viewModel: CharacteristicsViewModelType) {
        self.dataSource = dataSource
        self.viewModel = viewModel
        super.init(nibName: nil, bundle: nil)
        view.backgroundColor = .white
    }

    @available(*, unavailable)
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func loadView() {
        self.view = ViewClass()
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        setupTableView()
        setDataSourceRefreshBlock()
        bindViewModel()
    }

    private func setupTableView() {
        customView.setTableView(dataSource: dataSource, delegate: self)
        registerCells()
    }

    private func setDataSourceRefreshBlock() {
        self.dataSource.setRefreshBlock { [weak self] in
            self?.customView.refreshTableView()
        }
    }

    private func bindViewModel() {
        subscribeViewModelOutputs()
        dataSource.bindItemsObserver(to: viewModel.characteristicsOutput)
    }

    private func subscribeViewModelOutputs() {
        subscribeDataUpdateOutput()
        subscribeAlertTriggerOutput()
    }

    private func subscribeDataUpdateOutput() {
        viewModel.dataUpdateOutput.subscribe(onNext: { [unowned self]  _ in
            self.customView.refreshTableView()
        }).disposed(by: disposeBag)
    }

    private func subscribeAlertTriggerOutput() {
        viewModel.alertTriggerOutput.subscribe(onNext: { [unowned self] message in
            self.showAlert(title: Constant.Strings.titleSuccess, message: message)
        }).disposed(by: disposeBag)
    }

    private func registerCells() {
        customView.register(cellType: CharacterisiticsTableViewCell.self,
                forCellReuseIdentifier: String(describing: CharacterisiticsTableViewCell.self))
    }

    private func addWriteActions(to actionSheet: UIAlertController) {
        let writeValueNotificationAction = UIAlertAction(title: Constant.Strings.titleWrite,
                style: .default) { _ in
            self.showWriteFieldForCharacteristic()
        }
        actionSheet.addAction(writeValueNotificationAction)
    }

    private func addReadActions(to actionSheet: UIAlertController) {
        let readValueNotificationAction = UIAlertAction(title: Constant.Strings.titleRead,
                style: .default) { _ in
            self.viewModel.triggerValueRead()
        }
        actionSheet.addAction(readValueNotificationAction)
    }

    private func addNotificationActions(to actionSheet: UIAlertController) {
        let turnNotificationOffAction = UIAlertAction(title: Constant.Strings.turnOffNotifications,
                style: .default) { _ in
            self.viewModel.setNotificationsState(enabled: false)
        }
        let turnNotificationOnAction = UIAlertAction(title: Constant.Strings.turnOnNotifications,
                style: .default) { _ in
            self.viewModel.setNotificationsState(enabled: true)
        }
        actionSheet.addAction(turnNotificationOffAction)
        actionSheet.addAction(turnNotificationOnAction)
    }

    private func addDismissAction(to actionSheet: UIAlertController) {
        let dismissAction = UIAlertAction(title: Constant.Strings.titleCancel,
                style: .cancel) { _ in
            self.dismiss(animated: true, completion: nil)
        }
        actionSheet.addAction(dismissAction)
    }

    fileprivate func showWriteFieldForCharacteristic() {
        let valueWriteController = UIAlertController(title: Constant.Strings.titleWriteValue,
                message: Constant.Strings.hexValue,
                preferredStyle: .alert)
        valueWriteController.addTextField { _ in
        }

        valueWriteController.addAction(UIAlertAction(title: Constant.Strings.titleCancel, style: .cancel, handler: nil))
        valueWriteController.addAction(UIAlertAction(title: Constant.Strings.titleWrite, style: .default) { _ in

            if let _text = valueWriteController.textFields?.first?.text {
                self.viewModel.writeValueForCharacteristic(hexadecimalString: _text)
            }

        })
        present(valueWriteController, animated: true, completion: nil)

    }

    private func showAlert(title: String, message: String) {
        let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
        let action = UIAlertAction(title: Constant.Strings.titleOk, style: .default) { _ in
            self.dismiss(animated: true)
        }
        alertController.addAction(action)
        present(alertController, animated: true)
    }
}

extension CharacteristicsViewController: UITableViewDelegate {
    func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
        return 140
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        guard let characteristic = dataSource.takeItemAt(index: indexPath.row) as? Characteristic else {
            return
        }
{'fraction_non_alphanumeric': 0.07660714285714286, 'fraction_numerical': 0.0005357142857142857, 'mean_word_length': 3.048066498012288, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, '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': '6546303', 'n_tokens_mistral': 2915, 'n_tokens_neox': 2751, 'n_words': 590}