# frozen_string_literal: true require 'state_machine' require 'tty-prompt' require 'awesome_print' require 'forwardable' require 'mobilis/logger' require 'mobilis/project' module Mobilis class InteractiveDesigner extend Forwardable attr_accessor :project attr_reader :prompt def_delegators :@project, :projects, :display state_machine :state, initial: :intialize do event :go_build do transition [:main_menu] => :build end event :go_add_omakase_stack_rails_project do transition [:main_menu] => :add_omakase_stack_rails_project end event :go_add_prime_stack_rails_project do transition [:main_menu] => :add_prime_stack_rails_project end event :go_add_postgresql_instance do transition [:main_menu] => :add_postgresql_instance end event :go_add_mysql_instance do transition [:main_menu] => :add_mysql_instance end event :go_add_redis_instance do transition [:main_menu] => :add_redis_instance end event :go_add_rack_project do transition [:main_menu] => :add_rack_project end event :go_edit_rails_project do transition [ :add_omakase_stack_rails_project, :add_prime_stack_rails_project, :edit_rails_controller, :edit_rails_model, :toggle_rails_api_mode, :main_menu ] => :edit_rails_project end event :go_generate do transition [:main_menu] => :generate end event :go_main_menu do transition to: :main_menu end event :go_rails_add_model do transition [:edit_rails_project] => :rails_add_model end event :go_rails_add_controller do transition [:edit_rails_project] => :rails_add_controller end event :go_rails_edit_controller do transition [:rails_add_controller] => :edit_rails_controller end event :go_rails_edit_model do transition [:rails_add_model] => :edit_rails_model end event :go_save_project do transition [:main_menu] => :save_project end event :go_toggle_rails_api_mode do transition [:edit_rails_project] => :toggle_rails_api_mode end event :go_edit_links_select_project do transition [:main_menu] => :edit_links_select_project end event :go_edit_links do transition [:edit_links_select_project] => :edit_links end after_transition any => any do |designer| puts "o0o VVVV ---- VVVV o0o" puts "-- Switched state to #{ designer.state_name } --" puts "o0o ^^^^ ---- ^^^^ o0o" end state :main_menu do def display project.display end def choices project_choices = projects.map do |project| { name: "Edit '#{ project.name }' project", value: -> { @selected_rails_project = project ; go_edit_rails_project } } end [ {name: "Add prime stack rails project", value: -> { go_add_prime_stack_rails_project }}, {name: "Add omakase stack rails project", value: -> { go_add_omakase_stack_rails_project }}, {name: "Add rack3 project", value: -> { go_add_rack_project }}, #{ name: "Add airflow server project", value: -> { go_add_airflow_server }}, #{ name: "Add airflow job project", value: -> { go_add_airflow_job_project }}, #{ name: "Add Docker registry", value: -> { go_add_docker_registry }}, #{ name: "Add Vue.js project", value: -> { go_add_vue_project }}, #{ name: "Add flask project", value: -> { go_add_flask_project }}, #{ name: "Add existing git project", value: -> { go_add_existing_git_project }}, { name: "Add redis instance", value: -> { go_add_redis_instance }}, { name: "Add postgresql instance", value: -> { go_add_postgresql_instance }}, { name: "Add mysql instance", value: -> { go_add_mysql_instance }}, #{ name: "Add couchdb instance", value: -> { go_add_couchdb_instance }}, #{ name: "Add kafka instance", value: -> { go_add_kafka_instance }}, #{ name: "Add graphql instance", value: -> { go_add_grapql_instance }}, #{ name: "Add gitlab instance w/workers", value: -> { go_add_gitlab_instance }}, *project_choices, { name: "edit links", value: -> { go_edit_links_select_project }}, { name: "Save mproj.json", value: -> { go_save_project }}, { name: "Generate", value: -> { go_generate }}, { name: "Build", value: -> { go_build }} ] end def action = false end state :edit_links_select_project do def display = false def choices [ {name: "return to Main Menu", value: -> { go_main_menu }}, *( projects.map do |project| { name: "Edit '#{ project.name }' links", value: -> { @selected_project = project ; go_edit_links } } end) ] end def action = false end state :edit_links do def display = false def choices = false def action selected = prompt.multi_select("Select links") do |menu| menu.default *@selected_project.links projects.each do |project| menu.choice project.name unless project.name == @selected_project.name end end @selected_project.set_links selected go_main_menu end end state :edit_rails_model do def display ap @selected_rails_project.models.collect {|x| x[:name]} end def choices [ {name: "return to Main Menu", value: -> { go_main_menu }}, {name: "return to rails project edit", value: -> { go_edit_rails_project }}, {name: "Toggle timestamps", value: -> { go_toggle_rails_model_timestamps }}, *( @selected_rails_project.models.map do |model| { name: "Edit '#{ model.name }' model", value: -> { @selected_rails_model = model ; go_edit_rails_model } } end) ] end def action = false end state :edit_rails_project do def display @selected_rails_project.display end def choices [ {name: "return to Main Menu", value: -> { go_main_menu }}, {name: "Toggle API mode", value: -> { go_toggle_rails_api_mode }}, {name: "Add Model", value: -> { go_rails_add_model }}, {name: "Add Controller", value: -> { go_rails_add_controller }} ] end def action = false end state :add_prime_stack_rails_project do def display spacer end def choices = false def action project_name = prompt.ask("new Prime Stack Rails project name:") @selected_rails_project = project.add_prime_stack_rails_project project_name go_edit_rails_project end end state :add_rack_project do def display spacer end def choices = false def action project_name = prompt.ask("new Rack project name:") project.add_rack_project project_name go_main_menu end end state :add_omakase_stack_rails_project do def display spacer end def choices = false def action project_name = prompt.ask("new Omakase Stack Rails project name:") @selected_rails_project = project.add_omakase_stack_rails_project project_name go_edit_rails_project end end state :add_postgresql_instance do def display spacer end def choices = false def action project_name = prompt.ask("new postgresql instance name:") project.add_postgresql_instance project_name go_main_menu end end state :add_mysql_instance do def display spacer end def choices = false def action project_name = prompt.ask("new mysql instance name:") project.add_mysql_instance project_name go_main_menu end end state :add_redis_instance do def display spacer end def choices = false def action project_name = prompt.ask("new redis instance name:") project.add_redis_instance project_name go_main_menu end end state :toggle_rails_api_mode do def display Mobilis.logger.info "Toggled rails API mode for '#{@selected_rails_project.name}'" end def choices = false def action @selected_rails_project.toggle_rails_api_mode go_edit_rails_project end end state :rails_add_model do def display ap @selected_rails_project.models.collect {|x| x[:name]} end def choices = false def action name = prompt.ask("new model name") @selected_rails_model = add_model name go_edit_rails_model end end state :rails_add_controller do def display ap @selected_rails_project.controllers.collect {|x| x[:name]} end def choices = false def action name = prompt.ask("new controller name:") @selected_rails_controller = answer.add_controller name go_edit_rails_controller end end state :generate do def display spacer end def choices = false def action project.generate_files go_main_menu end end state :build do def display spacer end def choices = false def action project.build go_main_menu end end state :save_project do def display spacer end def choices = false def action project.save_project go_main_menu end end end def initialize super() @prompt = TTY::Prompt.new @project = Project.new end def choose_destination Mobilis.logger.info "#choose_destination" blank_space spacer display spacer blank_space if some_choices = choices then prompt.select("Choose your Path", some_choices, per_page: 20) else Mobilis.logger.info "No choices found, running action instead" action end end def new_relic_license_key ENV.fetch "NEW_RELIC_LICENSE_KEY", false end def spacer puts "|+--------------------------------------------------------+|" end def blank_space puts "" end end end