###main

/*

 * This source file was generated by the Gradle 'init' task

 */

package com.example.minitl;

import java.time.*;

import java.time.format.DateTimeFormatter;

import java.util.*;


public class Main {

    public static void main(String[] args) {


        //json読み込み



        if (args.length!=0){

            //コマンドライン実行

        }




        Scanner sc = new Scanner(System.in);

        PostStore store = new PostStore();

        System.err.println(store);

        DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");



        while (true) {

            System.out.println("======= minitl cli =======");

            System.out.println("1) post");

            System.out.println("2) list");

            System.out.println("3) like");

            System.out.println("4) delete");

            System.out.println("5) serch");

            System.out.println("6) quit");



            System.out.println("---choose number:");

            int choice = Integer.parseInt(sc.nextLine().trim());


            try {

                switch (choice) {


                    case 1 -> {

                        //投稿の追加

                        System.out.print("---write author: ");

                        String author = sc.nextLine();


                        System.out.print("---write body: ");

                        String body = sc.nextLine();


                        Post post = store.add(author, body);

                        System.out.println("created: " + post);

                    }


                    case 2 -> {

                        //投稿一覧の表示

                        for (Post post : store.list()) {

                            System.out.println("[id=" + post.id() + "] " + post.author() + " likes=" + post.likeCount() + " " + post.createdAt().format(timeFormatter) + "\n" + post.body() + "\n");

                        }

                    }



                    case 3 -> {

                        //投稿へのlike

                        System.out.println("---choose id: ");

                        long id = Long.parseLong(sc.nextLine());


                        store.like(id);

                        System.out.println("liked!");

                    }

                    


                    case 4 -> {

                        //投稿の削除

                        System.out.println("---choose id: ");

                        long id = Long.parseLong(sc.nextLine());


                        store.delete(id);

                        System.out.println("deleted!");

                    }


                    case 5 -> {

                        //投稿のキーワード検索

                        System.out.println("---input keyword");

                        String keyword = sc.nextLine();

                        

                        List<Post> result = store.search(keyword);

                        System.out.println(result);

                    }

                    

                    case 6 -> {

                        //終了

                        System.out.println("quited");

                        return;

                    }



                    default -> System.out.println("invalid");

                }


            } catch (PostNotFoundException e) {

                System.out.println("[Post not found] " + e.getMessage());

            } catch (IllegalArgumentException e) {

                System.out.println("[Invalid input] " + e.getMessage());

            }

        }


        //json保存

    }

}


###post

package com.example.minitl;

import java.time.LocalDateTime;


public record Post(long id, String author, String body, int likeCount, LocalDateTime createdAt) {}


###poststore

package com.example.minitl;

import java.util.*;

import java.util.stream.Collectors;

import java.time.*;



public class PostStore {

    private final List<Post> posts = new ArrayList<>();

    private long nextId = 1;



    //add(auther, body)->新しいpostをつくって先頭に追加し、返す

    public Post add(String author, String body) {


        if (author.isBlank() || author.length() > 20) {

            throw new IllegalArgumentException("author must be 1-20 characters");

        }

        if (body.isBlank() || body.length() > 140) {

            throw new IllegalArgumentException("body must be 1-140 characters");

        }



        LocalDateTime createdAt = LocalDateTime.now(ZoneId.of("Asia/Tokyo"));

        Post post = new Post(nextId++, author, body, 0, createdAt);

        posts.add(0, post); // 先頭に追加

        return post;

    }


    //list()ー>全件を新しい順でかえす

    public List<Post> list() {

        return new ArrayList<>(posts);

    }


    //like(id)->likeCountを+1した新しいpostに差し替える。なければ例外


    public void like(long id) {

        for (int i = 0; i < posts.size(); i++) {

            Post post = posts.get(i);

            if (post.id() == id) {

                Post updated = new Post(post.id(), post.author(), post.body(), post.likeCount() + 1, post.createdAt());

                posts.set(i, updated);

                return;

            }

        }

        throw new PostNotFoundException(id);

    }


        // delete(id)->削除する。存在しなければ例外

    public void delete(long id) {

        boolean isRemoved = posts.removeIf(post -> post.id() == id);

        if (!isRemoved) {

            throw new PostNotFoundException(id);

        }

    }



    //serch <keyword>キーワード検索

    public List<Post> search(String keyword){

        List<Post> result = posts.stream()

        .filter(p -> p.body().contains(keyword))

        .collect(Collectors.toList());

        return result;

    }

}

###PostE

package com.example.minitl;


public class PostNotFoundException extends RuntimeException {

    public PostNotFoundException(long id) {

        super("id:" + id + " is not found");

    }

}