<commit_before>module OpenAssets
  class BalanceCheck

    def coins_issued_on_product(product)
      expected = expected_coins_on_product(product)
      coinholder_data = coinholders_on_asset_address(product)
      if !coinholder_data['coinholders']
        puts "cannot get data"
        false
      else
        puts coinholder_data
        existing = sum_coins_with_holders(coinholder_data)
        existing >= expected
      end
    end

    def coinholders_on_asset_address(product)
      remote = OpenAssets::Remote.new("http://coins.assembly.com/")
      if product.coin_info
        asset_id = product.coin_info.asset_address
        if asset_id
          end_url = "v2/coinholders/#{asset_id}"
          coinholders = remote.get end_url
        end
      end
    end

    def sum_coins_with_holders(coinholder_data)
      owners = coinholder_data['coinholders']['owners']
      owners.sum{|a| a['asset_quantity'].to_i}
    end

    def expected_coins_on_product(product)
      if product.state == ['greenlit', 'profitable']
        10_000_000
      else
        0
      end
    end

    def expected_coins_on_user_for_product(user, product)
      TransactionLogEntry.where(product_id: product.id).where(wallet_id: user.id).sum(:cents)
    end

    def coins_on_user_product(coinholder_data, product)
      owners = coinholder_data['coinholders']['owners']
      r = []
      owners.each do |a|
        address = a['address']
        if user = User.find_by(wallet_public_address: address)
          expected_amount = expected_coins_on_user_for_product(user, product).to_i
          actual_amount = a['asset_quantity'].to_i
          if expected_amount != actual_amount
            r.append([user.username, user.wallet_public_address, actual_amount, expected_amount, expected_amount - actual_amount])
            puts "BAD USER AMOUNT ON #{product.name} for #{user.username} at #{user.wallet_public_address} has #{actual_amount} and should have #{expected_amount}"
          end
        end
      end
      r
    end

    def check_users_balances_on_product(product)
      coinholder_data = coinholders_on_asset_address(product)
      coins_on_user_product(coinholder_data, product)
    end

    def rectify_coins_on_product(product)
      diff = check_users_balances_on_product(product)
      diff.each do |d|
        coindiff = d[4]
        if coindiff < 0
          coins = -1 * coindiff
          puts "SENDING #{coins} back to #{product.name} from #{user.username}"
          OpenAssets::Transactions.new.return_coins_to_product_address(user, product, coins)
        elsif coindiff > 0
          coins = coindiff<commit_msg>supply btc for return txs<commit_after>module OpenAssets
  class BalanceCheck

    def coins_issued_on_product(product)
      expected = expected_coins_on_product(product)
      coinholder_data = coinholders_on_asset_address(product)
      if !coinholder_data['coinholders']
        puts "cannot get data"
        false
      else
        puts coinholder_data
        existing = sum_coins_with_holders(coinholder_data)
        existing >= expected
      end
    end

    def coinholders_on_asset_address(product)
      remote = OpenAssets::Remote.new("http://coins.assembly.com/")
      if product.coin_info
        asset_id = product.coin_info.asset_address
        if asset_id
          end_url = "v2/coinholders/#{asset_id}"
          coinholders = remote.get end_url
        end
      end
    end

    def sum_coins_with_holders(coinholder_data)
      owners = coinholder_data['coinholders']['owners']
      owners.sum{|a| a['asset_quantity'].to_i}
    end

    def expected_coins_on_product(product)
      if product.state == ['greenlit', 'profitable']
        10_000_000
      else
        0
      end
    end

    def expected_coins_on_user_for_product(user, product)
      TransactionLogEntry.where(product_id: product.id).where(wallet_id: user.id).sum(:cents)
    end

    def coins_on_user_product(coinholder_data, product)
      owners = coinholder_data['coinholders']['owners']
      r = []
      owners.each do |a|
        address = a['address']
        if user = User.find_by(wallet_public_address: address)
          expected_amount = expected_coins_on_user_for_product(user, product).to_i
          actual_amount = a['asset_quantity'].to_i
          if expected_amount != actual_amount
            r.append([user.username, user.wallet_public_address, actual_amount, expected_amount, expected_amount - actual_amount])
            puts "BAD USER AMOUNT ON #{product.name} for #{user.username} at #{user.wallet_public_address} has #{actual_amount} and should have #{expected_amount}"
          end
        end
      end
      r
    end

    def check_users_balances_on_product(product)
      coinholder_data = coinholders_on_asset_address(product)
      coins_on_user_product(coinholder_data, product)
    end

    def rectify_coins_on_product(product)
      diff = check_users_balances_on_product(product)
      diff.each do |d|
        coindiff = d[4]
        if coindiff < 0
          coins = -1 * coindiff
          puts "SENDING #{coins} back to #{product.name} from #{user.username}"
          OpenAssets::Transactions.new.send_btc(user.wallet_public_address, 0.00001)
          OpenAssets::Transactions.new.return_coins_to_product_address(user, product, coins)
        elsif coindiff > 0
          coins = coindiff
{'fraction_non_alphanumeric': 0.08434183578477006, 'fraction_numerical': 0.006330292310556694, 'mean_word_length': 2.889934829833454, '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': '2992457', 'n_tokens_mistral': 1667, 'n_tokens_neox': 1612, 'n_words': 321}