require 'git'
require 'json'
require 'fileutils'
require 'logger'
require 'canzea'

# canzea --lifecycle=wire --solution=gogs --action=push-content --args='{"file":"metadata.json","path":"test/a/metadata.json", "comment":"V1.0"}'
# canzea --util=push-config git@165.227.87.135:root/ecosystem.git "Latest Input" --args='{"files":[{"file":"metadata.json","path":"test/a/metadata.json"}]}'

# PushConfig.new.write "Test", "nr-global.flow", "new content and more and more"

# PushConfig.new.cp "Another bit of file", "nr-global.flow", "node-red/nr-global.flow"


class PushConfig
    def initialize (_relPath = "instances/#{ENV['HOSTNAME']}/config/")
        @relPath = _relPath
        @log = Logger.new(Canzea::config[:logging_root] + '/plans.log')
    end

    def cat(filePath)
        write filePath, File.read(filePath)
    end

    def cp(filePath, destPath)
        write destPath, File.read(filePath)
    end

    def write(filePath, contents)
        path = "ecosystems/#{ENV['ECOSYSTEM']}/#{@relPath}#{filePath}"

        begin
            folder = "_working"

            if File.exists? folder
                g = Git.init(folder)
            else
                g = Git.clone(ENV['ECOSYSTEM_CONFIG_GIT'], folder, :path => '.')
            end
            FileUtils.mkdir_p File.dirname("#{folder}/#{path}")

            open("#{folder}/#{path}", 'w') { |f|
              f.puts contents
            }

            g.add("#{path}")

        rescue => exception
            @log.error("PushConfig Failed")
            @log.error(exception.to_s)
            @log.error(exception.backtrace)
            abort()
        end

    end

    def commit(comment)
        folder = "_working"

        begin
            count = 0


            g = Git.init(folder)

            g.chdir do
              g.status.changed.each do |file|
                    count = count +1
              end
              g.status.added.each do |file|
                    count = count +1
              end
              g.status.deleted.each do |file|
                    count = count +1
              end
            end

            if count == 0
              log "No changes"
            else
              log "#{count} changes committed."
              g.commit(comment)

              g.push
            end

            FileUtils.rm_rf(folder)
        rescue => exception
            FileUtils.rm_rf(folder)
            @log.error("PushConfig Failed")
            @log.error(exception.to_s)
            @log.error(exception.backtrace)
            abort()
        end
    end

    def do(url, comment, params)
        begin

            # "git@#{ENV["GOGS_ADDRESS"]}:root/ecosystem.git"

            folder = "_working"

            FileUtils.rm_rf(folder)

            g = Git.clone(url, folder, :path => '.')

            params['files'].each { | f |
                file = f['file']

                path = f['path']

                FileUtils.mkdir_p File.dirname("#{folder}/#{path}")

                open("#{folder}/#{path}", 'w') { |f|
                  f.puts File.read(file)
                }
                g.add("#{path}")
            }


            count = 0
            g.chdir do
              g.status.changed.each do |file|
                    count = count +1
              end
              g.status.added.each do |file|
                    count = count +1
              end
              g.status.deleted.each do |file|
                    count = count +1
              end
            end

            if count == 0
              log "No changes"
            else
              log "#{count} changes committed."
              g.commit(comment)

              g.push
            end
        rescue => exception
            @log.error("PushConfig Failed")
            @log.error(exception.to_s)
            @log.error(exception.backtrace)
            abort()
        end
    end

    def log (msg)
        puts msg
        @log.info(msg)
    end
end