# frozen_string_literal: true

require_relative './post'
require 'json'
require 'singleton'

class Timeline
  def initialize
    json = load_json!
    posts = convert_posts(json)
    @posts = posts
  end

  def index
    @posts
  end

  def add(post)
    @posts.append(post)
    save
  end

  def remove; end

  def to_s(format = nil)
    @posts.map{ |post| post.to_s(format) }.join("\n")
  end

  def to_json(*_args)
    JSON.pretty_generate(
      @posts.map(&:to_h)
    )
  end

  def self.exist?
    File.exist?(Timeline.store_path)
  end

  def self.init
    File.open(Timeline.store_path, 'w') do |f|
      f.puts('[]')
    end
  end

  private

  def symbolize_keys(hash)
    hash.transform_keys(&:to_sym)
  end

  def save
    File.open(Timeline.store_path, 'w') do |f|
      f.puts(to_json)
    end
  end

  def load_json!
    unless File.exist?(Timeline.store_path)
      raise RuntimeError.new('json not found')
    end

    File.open(Timeline.store_path) do |f|
      JSON.parse(f.read, symbolize_names: true)
    end

  rescue JSON::ParserError
    raise RuntimeError.new('invalid json')
  end

  def convert_posts(json)
    json.map { |post| Post.new(post) }
  rescue ArgumentError
    raise RuntimeError.new('invalid json format')
  end

  def self.store_path
    dir = ENV['SELF_LOGGER_DIR'] || './'

    "#{dir}/posts.json"
  end
end
