# frozen_string_literal: true

# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

require 'cocoapods'
require 'digest'
require 'optparse'
require 'plist'
require 'tmpdir'
require 'xcodeproj'

DEFAULT_TESTAPP_TARGET = "testApp"

# Default sources of min iOS version
SOURCES=["https://cdn.cocoapods.org/"]
MIN_IOS_VERSION="12.0"
NOTICES_OUTPUT_PATH="./CoreOnly/NOTICES"
SEARCH_LOCAL_POD_VERSION=false

@options = {
    sources: SOURCES,
    min_ios_version: MIN_IOS_VERSION,
    output_path: NOTICES_OUTPUT_PATH,
    search_local_pod_version: false
}
begin
  OptionParser.new do |opts|
    opts.banner = "Usage: app.rb [options]"
    opts.on('-p', '--pods PODS', 'Pods separated by space or comma.') { |v| @options[:pods] = v.split(/[ ,]/) }
    opts.on('-s', '--sources SOURCES', 'Sources of Pods') { |v| @options[:sources] = v.split(/[ ,]/) }
    opts.on('-m', '--min_ios_version MIN_IOS_VERSION', 'Minimum iOS version') { |v| @options[:min_ios_version] = v }
    opts.on('-n', '--notices_path OUTPUT_PATH', 'The output path of NOTICES') { |v| @options[:output_path] = v }
    opts.on('-v', '--search_local_pod_version', 'Attach the latest pod version to a pod in Podfile') { |v| @options[:search_local_pod_version] = true }
  end.parse!

  raise OptionParser::MissingArgument if @options[:pods].nil?
rescue OptionParser::MissingArgument
  puts "Argument `--pods` should not be empty."
  raise
end

PODS = @options[:pods]
SOURCES = @options[:sources]
MIN_IOS_VERSION = @options[:min_ios_version]
NOTICES_OUTPUT_PATH = @options[:output_path]
SEARCH_LOCAL_POD_VERSION = @options[:search_local_pod_version]

def create_podfile(path: , sources: , target: , pods: [], min_ios_version: , search_local_pod_version: )
  output = ""
  for source in sources do
    output += "source \'#{source}\'\n"
  end
  if search_local_pod_version
    for source in sources do
      if source == "https://cdn.cocoapods.org/"
        next
      end
      `pod repo add #{Digest::MD5.hexdigest source} #{source}`
    end
  end
  output += "use_frameworks! :linkage => :static\n"

  output += "platform :ios, #{min_ios_version}\n"
  output += "target \'#{target}\' do\n"
  for pod in pods do
    if search_local_pod_version
      # `pod search` will search a pod locally and generate a corresonding pod
      # config in a Podfile with `grep`, e.g.
      # pod search Firebase | grep "pod.*" -m 1
      # will generate
      # pod 'Firebase', '~> 9.0.0'
      output += `pod search "#{pod}" | grep "pod.*" -m 1`
    else
      output += "pod \'#{pod}\'\n"
    end
  end
  output += "end\n"

# Remove default footers and headers generated by CocoaPods.
  output += "
    class ::Pod::Generator::Acknowledgements
      def header_text
    ''
      end
      def header_title
     ''
      end
      def footnote_text
      ''
      end
    end
  "
  puts "------Podfile------\n#{output}\n-------------------\n"
  podfile = File.new("#{path}/Podfile", "w")
  podfile.puts(output)
  podfile.close
end

def generate_notices_content(sources: SOURCES, pods: PODS, min_ios_version: MIN_IOS_VERSION)
  content = ""
  Dir.mktmpdir do |temp_dir|
    Dir.chdir(temp_dir) do
      project_path = "#{temp_dir}/barebone_app.xcodeproj"
      project_path = "barebone_app.xcodeproj"
      project = Xcodeproj::Project.new(project_path)
      project.new_target(:application, DEFAULT_TESTAPP_TARGET, :ios)
      project.save()
      create_podfile(path: temp_dir, sources: sources, target: DEFAULT_TESTAPP_TARGET,pods: pods, min_ios_version: min_ios_version, search_local_pod_version: SEARCH_LOCAL_POD_VERSION)
      pod_install_result = `pod install --allow-root`
      puts pod_install_result
      licenses = Plist.parse_xml("Pods/Target Support Files/Pods-testApp/Pods-testApp-acknowledgements.plist")

      existing_licenses={}
      for license in licenses["PreferenceSpecifiers"] do
        if existing_licenses.include?(license["FooterText"])
          existing_licenses.store(license["FooterText"], existing_licenses.fetch(license["FooterText"])+"\n"+license["Title"])
          next
        end
        existing_licenses.store(license["FooterText"], license["Title"])
      end
      existing_licenses.each{ |license, title|
        # The NOTICES format is like:
        # ```
        # ${title}
        # ${license}
        #
        # ${title}
        # ${license}
        # ...
        # ```
        content += "#{title}\n#{license}\n\n"
      }
    end
  end
  return content.strip
end

def main()
  content = generate_notices_content(sources: SOURCES, pods: PODS, min_ios_version: MIN_IOS_VERSION)
  notices = File.new(NOTICES_OUTPUT_PATH, "w")
  notices.puts(content)
  notices.close
end

main()
