# frozen_string_literal: true

require 'shellwords'

module Security
  # :nodoc:
  class Keychain
    DOMAINS = %i[user system common dynamic].freeze

    attr_reader :filename

    def initialize(filename)
      @filename = filename
    end

    def info
      system %(security show-keychain-info #{@filename.shellescape})
    end

    def lock
      system %(security lock-keychain #{@filename.shellescape})
    end

    def unlock(password)
      system %(security unlock-keychain -p #{password.shellescape} #{@filename.shellescape})
    end

    def delete
      system %(security delete-keychain #{@filename.shellescape})
    end

    class << self
      def create(filename, password)
        raise NotImplementedError
      end

      def list(domain = :user)
        raise ArgumentError "Invalid domain #{domain}, expected one of: #{DOMAINS}" unless DOMAINS.include?(domain)

        keychains_from_output(`security list-keychains -d #{domain}`)
      end

      def lock
        system %(security lock-keychain -a)
      end

      def unlock(password)
        system %(security unlock-keychain -p #{password.shellescape})
      end

      def default_keychain
        keychains_from_output(`security default-keychain`).first
      end

      def login_keychain
        keychains_from_output(`security login-keychain`).first
      end

      private

      def keychains_from_output(output)
        output.split(/\n/).collect { |line| new(line.strip.gsub(/^"|"$/, '')) }
      end
    end
  end
end
