# Uncomment this line to define a global platform for your project
# platform :ios, '9.0'

# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'

def parse_KV_file(file,separator='=')
  file_abs_path = File.expand_path(file)
  if !File.exists? file_abs_path
    return [];
  end
  pods_ary = []
  skip_line_start_symbols = ["#", "/"]
  File.foreach(file_abs_path) { |line|
      next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ }
      plugin = line.split(pattern=separator)
      if plugin.length == 2
        podname = plugin[0].strip()
        path = plugin[1].strip()
        podpath = File.expand_path("#{path}", file_abs_path)
        pods_ary.push({:name => podname,:path=>podpath});
      else
        puts "Invalid plugin specification: #{line}"
      end
  }
  return pods_ary
end

target 'Runner' do
  # Flutter Pods
  generated_xcode_build_settings = parse_KV_file("./Flutter/Generated.xcconfig")
  if generated_xcode_build_settings.empty?
    puts "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter build or flutter run is executed once first."
  end
  generated_xcode_build_settings.map{ |p|
    if p[:name]=='FLUTTER_FRAMEWORK_DIR'
      pod 'Flutter', :path => p[:path]
    end
  }

  # Plugin Pods
  plugin_pods = parse_KV_file("../.flutter-plugins")
  plugin_pods.map{ |p|
    pod p[:name], :path => File.expand_path("ios",p[:path])
  }
end

post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['PROVISIONING_PROFILE_SPECIFIER'] = ''
      config.build_settings['ENABLE_BITCODE'] = 'NO'
    end
  end
end