module Souls
  STRAINS = ["service", "api", "graph", "media", "admin"]
  module Init
    class << self
      def create_souls strain: 1, app_name: "souls"
        config_needed = (1..3)
        project = {}
        project[:strain] = STRAINS[strain.to_i - 1]
        begin
          puts "Google Cloud Main PROJECT_ID(This project will controll Cloud DNS):      (default: elsoul2)"
          project[:main_project_id] = STDIN.gets.chomp
          project[:main_project_id] == "" ? project[:main_project_id] = "elsoul2" : true
          puts "Google Cloud PROJECT_ID:      (default: elsoul2)"
          project[:project_id] = STDIN.gets.chomp
          project[:project_id] = "elsoul2" if project[:project_id] == ""
          puts "VPC Network Name:          (default: default)"
          project[:network] = STDIN.gets.chomp
          project[:network] == "" ? project[:network] = "default" : true
          puts "Namespace:          (default: souls)"
          project[:namespace] = STDIN.gets.chomp
          project[:namespace] == "" ? project[:namespace] = "souls" : true
          if project[:strain] == "service"
            puts "Service Name:          (default: blog-service)"
            project[:service_name] = STDIN.gets.chomp
            project[:service_name] == "" ? project[:service_name] = "blog-service" : true
          end
          puts "Instance MachineType:       (default: custom-1-6656)"
          project[:machine_type] = STDIN.gets.chomp
          project[:machine_type] == "" ? project[:machine_type] = "custom-1-6656" : true
          puts "Zone:           (default: us-central1-a)"
          project[:zone] = STDIN.gets.chomp
          project[:zone] == "" ? project[:zone] = "us-central1-a" : true
          puts "Domain:          (e.g API: el-soul.com, Serive: xds:///blog-service:8000)"
          project[:domain] = STDIN.gets.chomp
          project[:domain] == "" ? project[:domain] = "el-soul.com" : true
          puts "Google Application Credentials Path:      (default: #{app_name}/config/credentials.json)"
          project[:google_application_credentials] = STDIN.gets.chomp
          project[:google_application_credentials] == "" ? project[:google_application_credentials] = "./config/credentials.json" : true
          puts project
          puts "Enter to finish set up!"
          confirm = STDIN.gets.chomp
          raise StandardError, "Retry" unless confirm == ""
          download_souls app_name: app_name, repository_name: "souls_#{STRAINS[strain.to_i - 1]}"
          initial_config_init app_name: app_name, project: project if config_needed.include?(strain)
        rescue StandardError => error
          puts error
          retry
        end
      end

      def initial_config_init app_name: "souls", project: {}
        `touch "#{app_name}/config/initializers/souls.rb"`
        file_path = "#{app_name}/config/initializers/souls.rb"
        File.open(file_path, "w") do |f|
          f.write <<~EOS
            Souls.configure do |config|
              config.main_project_id = "#{project[:main_project_id]}"
              config.project_id = "#{project[:project_id]}"
              config.app = "#{app_name}"
              config.namespace = "#{project[:namespace]}"
              config.service_name = "#{project[:service_name]}"
              config.network = "#{project[:network]}"
              config.machine_type = "#{project[:machine_type]}"
              config.zone = "#{project[:zone]}"
              config.domain = "#{project[:domain]}"
              config.google_application_credentials = "#{project[:google_application_credentials]}"
              config.strain = "#{project[:strain]}"
              config.proto_package_name = "souls"
            end
          EOS
        end
      end

      def config_init app_name: "souls", project: {}
        `touch ./config/initializers/souls.rb`
        file_path = "./config/initializers/souls.rb"
        puts "Generating souls conf..."
        sleep(rand(0.1..0.3))
        puts "Generated!"
        puts "Let's Edit SOULs Conf: `#{file_path}`"
        File.open(file_path, "w") do |f|
          f.write <<~EOS
            Souls.configure do |config|
              config.main_project_id = "#{project[:main_project_id]}"
              config.project_id = "#{project[:project_id]}"
              config.app = "#{app_name}"
              config.namespace = "#{project[:namespace]}"
              config.service_name = "#{project[:service_name]}"
              config.network = "#{project[:network]}"
              config.machine_type = "#{project[:machine_type]}"
              config.zone = "#{project[:zone]}"
              config.domain = "#{project[:domain]}"
              config.google_application_credentials = "#{project[:google_application_credentials]}"
              config.strain = "#{project[:strain]}"
              config.proto_package_name = "souls"
            end
          EOS
        end
      end

      def get_version repository_name: "souls_service"
        data = JSON.parse `curl \
        -H "Accept: application/vnd.github.v3+json" \
        -s https://api.github.com/repos/elsoul/#{repository_name}/releases`
        data[0]["tag_name"]
      end

      def download_souls app_name: "souls", repository_name: "souls_service"
        version = get_version repository_name: repository_name
        system "curl -OL https://github.com/elsoul/#{repository_name}/archive/#{version}.tar.gz"
        system "tar -zxvf ./#{version}.tar.gz"
        system "mkdir #{app_name}"
        folder = version.delete "v"
        system "cp -r #{repository_name}-#{folder}/ #{app_name}/"
        system "rm -rf #{version}.tar.gz && rm -rf #{repository_name}-#{folder}"
        txt = <<~TEXT
           _____ ____  __  ____#{'        '}
          / ___// __ \\/ / / / /   _____
          \\__ \\/ / / / / / / /   / ___/
         ___/ / /_/ / /_/ / /___(__  )#{' '}
        /____/\\____/\\____/_____/____/#{'  '}
        TEXT
        puts txt
        puts "=============================="
        puts "Welcome to SOULs!"
        puts "SOULs Version: #{Souls::VERSION}"
        puts "=============================="
        puts "$ cd #{app_name}"
        puts "------------------------------"
      end

      def proto proto_package_name: "souls", service: "blog"
        system "grpc_tools_ruby_protoc -I ./protos --ruby_out=./app/services --grpc_out=./app/services ./protos/#{service}.proto"
        service_pb_path = "./app/services/#{service}_services_pb.rb"
        new_file = "./app/services/#{proto_package_name}.rb"
        File.open(new_file, "w") do |new_line|
          File.open(service_pb_path, "r") do |f|
            f.each_line.with_index do |line, i|
              case i
              when 0
                new_line.write "# Generated by the SOULs protocol buffer compiler.  DO NOT EDIT!\n"
              when 3
                next
              else
                puts "#{i}: #{line}"
                new_line.write line.to_s
              end
            end
          end
        end
        FileUtils.rm service_pb_path
        puts "SOULs Proto Created!"
      end

      def service_deploy
        service_name = Souls.configuration.service_name
        health_check_name = "#{service_name}-hc"
        firewall_rule_name = "#{service_name}-allow-health-checks"
        zone = Souls.configuration.zone
        url_map_name = "#{service_name}-url-map"
        path_matcher_name = "#{service_name}-path-mathcher"
        port = "5000"
        proxy_name = "#{service_name}-proxy"
        forwarding_rule_name = "#{service_name}-forwarding-rule"

        Souls.create_service_account
        Souls.create_service_account_key
        Souls.add_service_account_role
        Souls.add_service_account_role role: "roles/containerregistry.ServiceAgent"
        Souls.create_health_check health_check_name: health_check_name
        Souls.create_firewall_rule firewall_rule_name: firewall_rule_name
        Souls.create_backend_service service_name: service_name, health_check_name: health_check_name
        Souls.export_network_group
        file_path = "./config/neg_name"
        File.open(file_path) do |f|
          Souls.add_backend_service service_name: service_name, neg_name: f.gets.to_s, zone: zone
        end
        Souls.create_url_map url_map_name: url_map_name, service_name: service_name
        Souls.create_path_matcher url_map_name: url_map_name, service_name: service_name, path_matcher_name: path_matcher_name, hostname: app, port: port
        Souls.create_target_grpc_proxy proxy_name: proxy_name, url_map_name: url_map_name
        Souls.create_forwarding_rule forwarding_rule_name: forwarding_rule_name, proxy_name: proxy_name, port: port
      end

      def api_deploy
        Souls.service_api_enable
        Souls.create_service_account
        Souls.create_service_account_key
        Souls.add_service_account_role
        Souls.add_service_account_role role: "roles/containerregistry.ServiceAgent"
        Souls.config_set
        Souls.create_network
        Souls.create_cluster
        Souls.get_credentials
        Souls.create_namespace
        Souls.create_ip
        Souls.create_ssl
        Souls.apply_deployment
        Souls.apply_service
        Souls.apply_ingress
        puts "Wainting for Ingress to get IP..."
        sleep 1
        puts "This migth take a few mins..."
        sleep 90
        Souls.create_dns_conf
        Souls.config_set_main
        Souls.set_dns
        Souls.config_set
      end

      def local_deploy
        `souls i run_psql`
        `docker pull`
      end

      def service_update
        `souls i apply_deployment`
      end

      def api_update
        `souls i apply_deployment`
      end

      def service_delete
        service_name = Souls.configuration.service_name
        firewall_rule_name = "#{service_name}-allow-health-checks"
        url_map_name = "#{service_name}-url-map"
        proxy_name = "#{service_name}-proxy"
        forwarding_rule_name = "#{service_name}-forwarding-rule"

        Souls.delete_forwarding_rule forwarding_rule_name: forwarding_rule_name
        Souls.delete_target_grpc_proxy proxy_name: proxy_name
        Souls.delete_url_map url_map_name: url_map_name
        Souls.delete_backend_service service_name: service_name
        Souls.delete_health_check health_check_name: health_check_name
        Souls.delete_firewall_rule firewall_rule_name: firewall_rule_name
      end

      def api_delete
        `souls i delete_deployment`
        `souls i delete_secret`
        `souls i delete_service`
        `souls i delete_ingress`
      end

      def model class_name: "souls"
        file_path = "./app/models/#{class_name.singularize}.rb"
        File.open(file_path, "w") do |f|
          f.write <<~EOS
            class #{class_name.camelize} < ActiveRecord::Base
            end
          EOS
        end
        [file_path]
      end

      def type_check type
        {
          bigint: "Integer",
          string: "String",
          float: "Float",
          text: "String",
          datetime: "GraphQL::Types::ISO8601DateTime",
          date: "GraphQL::Types::ISO8601DateTime",
          boolean: "Boolean",
          integer: "Integer"
        }[type.to_sym]
      end

      def get_test_type type
        {
          bigint: 1,
          float: 4.2,
          string: '"MyString"',
          text: '"MyString"',
          datetime: "Time.now",
          date: "Time.now",
          boolean: false,
          integer: 1
        }[type.to_sym]
      end

      def table_check line: "", class_name: ""
        if line.include?("create_table") && (line.split(" ")[1].gsub("\"", "").gsub(",", "") == class_name.pluralize.to_s)
          return true
        end
        false
      end

      def create_mutation_head class_name: "souls"
        file_path = "./app/graphql/mutations/#{class_name}/create_#{class_name}.rb"
        File.open(file_path, "w") do |new_line|
          new_line.write <<~EOS
            module Mutations
              module #{class_name.camelize}
                class Create#{class_name.camelize} < BaseMutation
                  field :#{class_name}, Types::#{class_name.camelize}Type, null: false
                  field :error, String, null: true

          EOS
        end
      end

      def create_mutation_params class_name: "souls"
        file_path = "./app/graphql/mutations/#{class_name}/create_#{class_name}.rb"
        path = "./db/schema.rb"
        @on = false
        File.open(file_path, "a") do |new_line|
          File.open(path, "r") do |f|
            f.each_line.with_index do |line, i|
              if @on
                break if line.include?("end") || line.include?("t.index")
                field = "[String]" if line.include?("array: true")
                type, name = line.split(",")[0].gsub("\"", "").scan(/((?<=t\.).+(?=\s)) (.+)/)[0]
                field ||= type_check type
                case name
                when "created_at", "updated_at"
                  next
                else
                  new_line.write "      argument :#{name}, #{field}, required: false\n"
                end
              end
              @on = true if table_check(line: line, class_name: class_name)
            end
          end
        end
      end

      def create_mutation_end class_name: "souls"
        file_path = "./app/graphql/mutations/#{class_name}/create_#{class_name}.rb"
        File.open(file_path, "a") do |new_line|
          new_line.write <<~EOS

                  def resolve **args
                    #{class_name} = ::#{class_name.camelize}.new args
                    if #{class_name}.save
                      { #{class_name}: #{class_name} }
                    else
                      { error: #{class_name}.errors.full_messages }
                    end
                  rescue StandardError => error
                    GraphQL::ExecutionError.new error
                  end
                end
              end
            end
          EOS
        end
        file_path
      end

      def update_mutation_head class_name: "souls"
        file_path = "./app/graphql/mutations/#{class_name}/update_#{class_name}.rb"
        File.open(file_path, "w") do |new_line|
          new_line.write <<~EOS
            module Mutations
              module #{class_name.camelize}
                class Update#{class_name.camelize} < BaseMutation
                  field :#{class_name}, Types::#{class_name.camelize}Type, null: false

          EOS
        end
      end

      def update_mutation_params class_name: "souls"
        file_path = "./app/graphql/mutations/#{class_name}/update_#{class_name}.rb"
        path = "./db/schema.rb"
        @on = false
        File.open(file_path, "a") do |new_line|
          File.open(path, "r") do |f|
            f.each_line.with_index do |line, i|
              if @on
                break if line.include?("end") || line.include?("t.index")
                field = "[String]" if line.include?("array: true")
                type, name = line.split(",")[0].gsub("\"", "").scan(/((?<=t\.).+(?=\s)) (.+)/)[0]
                field ||= type_check type
                case name
                when "created_at", "updated_at"
                  next
                else
                  new_line.write "      argument :#{name}, #{field}, required: false\n"
                end
              end
              @on = true if table_check(line: line, class_name: class_name)
            end
          end
        end
      end

      def update_mutation_end class_name: "souls"
        file_path = "./app/graphql/mutations/#{class_name}/update_#{class_name}.rb"
        File.open(file_path, "a") do |new_line|
          new_line.write <<~EOS

                  def resolve **args
                    #{class_name} = ::#{class_name.camelize}.find args[:id]
                    #{class_name}.update args
                    { #{class_name}: ::#{class_name.camelize}.find(args[:id]) }
                  rescue StandardError => error
                    GraphQL::ExecutionError.new error
                  end
                end
              end
            end
          EOS
        end
        file_path
      end

      def update_mutation class_name: "souls"
        update_mutation_head class_name: class_name
        update_mutation_params class_name: class_name
        update_mutation_end class_name: class_name
      end

      def delete_mutation class_name: "souls"
        file_path = "./app/graphql/mutations/#{class_name}/delete_#{class_name}.rb"
        File.open(file_path, "w") do |f|
          f.write <<~EOS
            module Mutations
              module #{class_name.camelize}
                class Delete#{class_name.camelize} < BaseMutation
                  field :#{class_name}, Types::#{class_name.camelize}Type, null: false
                  argument :id, Integer, required: true

                  def resolve id:
                    #{class_name} = ::#{class_name.camelize}.find id
                    #{class_name}.destroy
                    { #{class_name}: #{class_name} }
                  rescue StandardError => error
                    GraphQL::ExecutionError.new error
                  end
                end
              end
            end
          EOS
        end
        file_path
      end

      def create_confirm dir_path: ""
        puts "Directory already exists, Overwrite?? (Y/N)\n#{dir_path}"
        input = STDIN.gets.chomp
        return true if input == "Y"
        raise StandardError.new "Directory Already Exist!\n#{dir_path}"
      end

      def mutation class_name: "souls"
        singularized_class_name = class_name.singularize
        if Dir.exist? "./app/graphql/mutations/#{singularized_class_name}"
          create_confirm dir_path: "./app/graphql/mutations/#{singularized_class_name}"
        else
          Dir.mkdir "./app/graphql/mutations/#{singularized_class_name}"
        end
        create_mutation_head class_name: singularized_class_name
        create_mutation_params class_name: singularized_class_name
        [
          create_mutation_end(class_name: singularized_class_name),
          update_mutation(class_name: singularized_class_name),
          delete_mutation(class_name: singularized_class_name)
        ]
      end

      def create_query class_name: "souls"
        file_path = "./app/graphql/queries/#{class_name.pluralize}.rb"
        File.open(file_path, "w") do |f|
          f.write <<~EOS
            module Queries
              class #{class_name.camelize.pluralize} < Queries::BaseQuery
                type [Types::#{class_name.camelize}Type], null: false

                def resolve
                  ::#{class_name.camelize}.all
                rescue StandardError => error
                  GraphQL::ExecutionError.new error
                end
              end
            end
          EOS
        end
        file_path
      end

      def create_queries class_name: "souls"
        file_path = "./app/graphql/queries/#{class_name}.rb"
        File.open(file_path, "w") do |f|
          f.write <<~EOS
            module Queries
              class #{class_name.camelize} < Queries::BaseQuery
                type Types::#{class_name.camelize}Type, null: false
                argument :id, Integer, required: true

                def resolve id:
                  ::#{class_name.camelize}.find(id)
                rescue StandardError => error
                  GraphQL::ExecutionError.new error
                end
              end
            end
          EOS
          file_path
        end
      end

      def query class_name: "souls"
        singularized_class_name = class_name.singularize
        [create_query(class_name: singularized_class_name), create_queries(class_name: singularized_class_name)]
      end

      def create_type_head class_name: "souls"
        file_path = "./app/graphql/types/#{class_name}_type.rb"
          File.open(file_path, "w") do |f|
            f.write <<~EOS
              module Types
                class #{class_name.camelize}Type < GraphQL::Schema::Object
                  implements GraphQL::Types::Relay::Node

            EOS
          end
      end

      def create_type_params class_name: "souls"
        file_path = "./app/graphql/types/#{class_name}_type.rb"
        path = "./db/schema.rb"
        @on = false
        File.open(file_path, "a") do |new_line|
          File.open(path, "r") do |f|
            f.each_line.with_index do |line, i|
              if @on
                new_line.write "\n" && break if line.include?("end") || line.include?("t.index")
                field = "[String]" if line.include?("array: true")
                type, name = line.split(",")[0].gsub("\"", "").scan(/((?<=t\.).+(?=\s)) (.+)/)[0]
                field ||= type_check type
                new_line.write "    field :#{name}, #{field}, null: true\n"
              end
              if table_check(line: line, class_name: class_name)
                @on = true
                new_line.write "    global_id_field :id\n"
              end
            end
          end
        end
      end

      def create_type_end class_name: "souls"
        file_path = "./app/graphql/types/#{class_name}_type.rb"
        File.open(file_path, "a") do |f|
          f.write <<~EOS
              end
            end
          EOS
        end
        [file_path]
      end

      def type class_name: "souls"
        singularized_class_name = class_name.singularize
        create_type_head class_name: singularized_class_name
        create_type_params class_name: singularized_class_name
        create_type_end class_name: singularized_class_name
      end

      def rspec_factory_head class_name: "souls"
        file_path = "./spec/factories/#{class_name.pluralize}.rb"
        File.open(file_path, "w") do |f|
          f.write <<~EOS
            FactoryBot.define do
              factory :#{class_name} do
          EOS
        end
      end

      def rspec_factory_params class_name: "souls"
        file_path = "./spec/factories/#{class_name.pluralize}.rb"
        path = "./db/schema.rb"
        @on = false
        File.open(file_path, "a") do |new_line|
          File.open(path, "r") do |f|
            f.each_line.with_index do |line, i|
              if @on
                new_line.write "\n" && break if line.include?("end") || line.include?("t.index")
                field = '["tag1", "tag2", "tag3"]' if line.include?("array: true")
                type, name = line.split(",")[0].gsub("\"", "").scan(/((?<=t\.).+(?=\s)) (.+)/)[0]
                field ||= get_test_type type
                new_line.write "    #{name} { #{field} }\n"
              end
              if table_check(line: line, class_name: class_name)
                @on = true
              end
            end
          end
        end
      end

      def rspec_factory_end class_name: "souls"
        file_path = "./spec/factories/#{class_name.pluralize}.rb"
        File.open(file_path, "a") do |f|
          f.write <<~EOS
              end
            end
          EOS
        end
        [file_path]
      end

      def rspec_factory class_name: "souls"
        singularized_class_name = class_name.singularize
        rspec_factory_head class_name: singularized_class_name
        rspec_factory_params class_name: singularized_class_name
        rspec_factory_end class_name: singularized_class_name
      end

      def rspec_model class_name: "souls"
        file_path = "./spec/models/#{class_name}_spec.rb"
        File.open(file_path, "w") do |f|
          f.write <<~EOS
            RSpec.describe #{class_name.camelize}, type: :model do
              it "作成する" do
                expect(FactoryBot.build(:#{class_name.singularize})).to be_valid
              end
            end
          EOS
        end
        [file_path]
      end

      def rspec_mutation class_name: "souls"
        # if needed
      end

      def rspec_query class_name: "souls"
        # if needed
      end

      def rspec_type class_name: "souls"
        # if needed
      end

      def get_end_point
        file_path = "./app/graphql/types/mutation_type.rb"
        File.open(file_path, "r") do |f|
          f.each_line.with_index do |line, i|
            return i if line.include?("end")
          end
        end
      end

      def get_tables
        path = "./db/schema.rb"
        tables = []
        File.open(path, "r") do |f|
          f.each_line.with_index do |line, i|
              tables << line.split("\"")[1] if line.include?("create_table")
          end
        end
        tables
      end

      def add_mutation_type class_name: "souls"
        # let's do this later
      end

      def add_query_type class_name: "souls"
        # let's do this later
      end

      def migrate class_name: "souls"
        singularized_class_name = class_name.singularize
        model_paths = model class_name: singularized_class_name
        type_paths = type class_name: singularized_class_name
        rspec_factory_paths = rspec_factory class_name: singularized_class_name
        rspec_model_paths = rspec_model class_name: singularized_class_name
        query_path = query class_name: singularized_class_name
        mutation_path = mutation class_name: singularized_class_name
        [
          model: model_paths,
          type: type_paths,
          rspec_factory: rspec_factory_paths,
          rspec_model: rspec_model_paths,
          query: query_path,
          mutation: mutation_path,
          add_query_type: [
            "    field :#{singularized_class_name}, resolver: Queries::#{singularized_class_name.camelize}",
            "    field :#{singularized_class_name.pluralize}, Types::#{singularized_class_name.camelize}Type.connection_type, null: true"
          ],
          add_mutation_type: [
            "    field :create_#{singularized_class_name}, mutation: Mutations::#{singularized_class_name.camelize}::Create#{singularized_class_name.camelize}",
            "    field :update_#{singularized_class_name}, mutation: Mutations::#{singularized_class_name.camelize}::Update#{singularized_class_name.camelize}",
            "    field :delete_#{singularized_class_name}, mutation: Mutations::#{singularized_class_name.camelize}::Delete#{singularized_class_name.camelize}"
          ]
        ]
      end

      def migrate_all
        puts "◆◆◆ Let's Auto Generate CRUD API ◆◆◆\n"
        `rake db:migrate`
        paths = get_tables.map do |class_name|
          migrate class_name: class_name.singularize
        end
        puts "\n============== Model ======================\n\n"
        paths.each do |class_name|
          class_name.each do |path|
            path[:model].each { |line| puts line }
          end
        end
        puts "\n============== Type =======================\n\n"
        paths.each do |class_name|
          class_name.each do |path|
            path[:type].each { |line| puts line }
          end
        end
        puts "\n============== FactoryBot =================\n\n"
        paths.each do |class_name|
          class_name.each do |path|
            path[:rspec_factory].each { |line| puts line }
          end
        end
        puts "\n============== RspecModel =================\n\n"
        paths.each do |class_name|
          class_name.each do |path|
            path[:rspec_model].each { |line| puts line }
          end
        end
        puts "\n============== Query ======================\n\n"
        paths.each do |class_name|
          class_name.each do |path|
            path[:query].each { |line| puts line }
          end
        end
        puts "\n============== Mutation ===================\n\n"
        paths.each do |class_name|
          class_name.each do |path|
            path[:mutation].each { |line| puts line }
          end
        end
        puts "\nAll files created from ./db/schema.rb"
        puts "\n\n"
        puts "\n##########################################################\n"
        puts "#                                                        #\n"
        puts "# Add These Lines at ./app/graphql/types/query_type.rb   #\n"
        puts "#                                                        #\n"
        puts "##########################################################\n\n\n"
        paths.each do |class_name|
          class_name.each do |path|
            path[:add_query_type].each { |line| puts line }
          end
        end
        puts "\n    ## Connection Type\n\n"
        get_tables.each do |class_name|
          puts "    def #{class_name.pluralize}"
          puts "      #{class_name.singularize.camelize}.all.order(id: :desc)"
          puts "    end\n\n"
        end
        puts "\n#############################################################\n"
        puts "#                                                           #\n"
        puts "# Add These Lines at ./app/graphql/types/mutation_type.rb   #\n"
        puts "#                                                           #\n"
        puts "#############################################################\n\n\n"
        paths.each do |class_name|
          class_name.each do |path|
            path[:add_mutation_type].each { |line| puts line }
          end
        end
      end
    end
  end
end