# Copyright (c) Toss.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

require 'json'
require 'pathname'

def use_brick_modules!
  brick_root = "#{Pod::Config.instance.installation_root}/.."
  discovered_modules = []
  
  begin
    # Discover Brick modules before running codegen
    discovered_modules = discover_brick_modules(brick_root)
    
    # Run brick-codegen with real-time output and colors (iOS only)
    exit_status = system("cd #{brick_root} && FORCE_COLOR=1 npx brick-codegen --platform ios")
    
    if exit_status
      # Generate BrickModuleProvider.swift for auto-registration
      generate_brick_module_provider(brick_root, discovered_modules)
      
      # Add generated BrickCodegen pod if it exists
      brick_codegen_podspec_path = "#{brick_root}/ios/.brick/BrickCodegen.podspec"
      brick_codegen_pod_path = "#{brick_root}/ios/.brick"
      
      if File.exist?(brick_codegen_podspec_path)
        begin
          pod 'BrickCodegen', :path => brick_codegen_pod_path
        rescue => pod_error
          Pod::UI.warn "[Brick] Failed to add BrickCodegen pod: #{pod_error.message}"
        end
      end
    else
      Pod::UI.warn "[Brick] brick-codegen failed to run. Please make sure it's installed: npm install brick-codegen"
    end
  rescue => e
    Pod::UI.warn "[Brick] Error running brick-codegen: #{e.message}"
  end
end

def discover_brick_modules(project_root)
  modules = []
  node_modules_path = File.join(project_root, 'node_modules')
  
  return modules unless File.exist?(node_modules_path)
  
  # Read the main package.json to get dependencies
  package_json_path = File.join(project_root, 'package.json')
  return modules unless File.exist?(package_json_path)
  
  begin
    package_json = JSON.parse(File.read(package_json_path))
    dependencies = (package_json['dependencies'] || {}).merge(package_json['devDependencies'] || {})
    
    dependencies.each do |dep_name, _version|
      dep_path = File.join(node_modules_path, dep_name)
      dep_package_json_path = File.join(dep_path, 'package.json')
      
      next unless File.exist?(dep_package_json_path)
      
      begin
        dep_package_json = JSON.parse(File.read(dep_package_json_path))
        
        # Check if this is a Brick module
        if dep_package_json['brickModule']
          brick_config = dep_package_json['brickModule']
          ios_config = brick_config['ios'] || {}
          
          # Check if autoRegister is enabled (default: true)
          auto_register = brick_config['autoRegister'] != false
          
          if auto_register
            # Extract the iOS module name and class name
            module_name = ios_config['moduleName']
            class_name = ios_config['className']
            
            modules << {
              'name' => dep_name,
              'moduleName' => module_name,
              'className' => class_name,
            }
            
            Pod::UI.puts "[Brick] Found module: #{dep_name} (#{module_name})"
          else
            Pod::UI.puts "[Brick] Skipping module (autoRegister=false): #{dep_name}"
          end
        end
      rescue => e
        Pod::UI.warn "[Brick] Failed to parse #{dep_package_json_path}: #{e.message}"
      end
    end
  rescue => e
    Pod::UI.warn "[Brick] Failed to discover modules: #{e.message}"
  end
  
  modules
end

def generate_brick_module_provider(project_root, modules)
  return if modules.empty?
  
  # Create the .brick directory if it doesn't exist
  brick_dir = File.join(project_root, 'ios', '.brick')
  FileUtils.mkdir_p(brick_dir) unless File.exist?(brick_dir)
  
  # Generate imports and module instances
  imports = modules.map { |m| "import #{m['moduleName']}" }.join("\n")
  module_instances = modules.map { |m| "            #{m['className']}()" }.join(",\n")
  module_names = modules.map { |m| "            \"#{m['moduleName']}\"" }.join(",\n")
  
  # Generate the Swift file content
  swift_content = <<-SWIFT
// Auto-generated by brick-module podfile_helper.rb
// Do not edit manually - this file is regenerated on each pod install

import Foundation
import BrickModule
#{imports}

@objcMembers
public class BrickModuleProvider: NSObject {
    @objc public static func registerAll() {
        let modules: [BrickModuleBase] = [
#{module_instances}
        ]
        
        if !modules.isEmpty {
            BrickModuleRegistry.shared.register(modules)
            print("🧱 BrickModuleProvider: Registered \\(modules.count) modules")
        }
    }
    
    @objc public static func getAvailableModules() -> [String] {
        return [
#{module_names}
        ]
    }
}
SWIFT
  
  # Write the Swift file
  provider_path = File.join(brick_dir, 'BrickModuleProvider.swift')
  File.write(provider_path, swift_content)
  
  # Generate simple Objective-C wrapper with clean name
  objc_header_content = <<-OBJC
// Auto-generated by brick-module podfile_helper.rb
// Simple Objective-C wrapper for auto-linking

#import <Foundation/Foundation.h>

@interface BrickModuleProviderObjC : NSObject
+ (void)registerAll;
@end
OBJC

  objc_impl_content = <<-OBJC
// Auto-generated by brick-module podfile_helper.rb
// Simple Objective-C wrapper implementation

#import "BrickModuleProviderObjC.h"
#import "BrickCodegen-Swift.h"

@implementation BrickModuleProviderObjC

+ (void)registerAll {
    [BrickModuleProvider registerAll];
}

@end
OBJC
  
  # Write Objective-C wrapper files
  objc_header_path = File.join(brick_dir, 'BrickModuleProviderObjC.h')
  objc_impl_path = File.join(brick_dir, 'BrickModuleProviderObjC.m')
  File.write(objc_header_path, objc_header_content)
  File.write(objc_impl_path, objc_impl_content)
  
  Pod::UI.puts "[Brick] Generated BrickModuleProvider.swift with #{modules.size} modules"
  Pod::UI.puts "[Brick] Generated BrickModuleProviderObjC wrapper for clean Objective-C integration"
end