#!/usr/bin/env python
# coding: utf-8

# Copyright (c) Saga Inc.
# Distributed under the terms of the GPL License.

from copy import deepcopy
from typing import List, Optional, Tuple
from mitosheet.code_chunks.code_chunk import CodeChunk
from mitosheet.state import State


class EmptyCodeChunk(CodeChunk):
    """
    A code chunk that generates no code, but has a title and a description
    comment, which is necessary for describing some steps in the step list
    even if they don't have generated code (like graphing).

    Notably, as they don't have generated code, we can still optimize out
    these steps in the code optimization process.

    You can also set optimize_right to be False, which will make sure that 
    this step does not get optimized out (e.g. see SetDataframeFormatCodeChunk
    for why we might want this).
    """

    def __init__(self, prev_state: State, display_name: str, description_comment: str, optimize_right: bool=True):
        super().__init__(prev_state)
        self.display_name = display_name
        self.description_comment = description_comment
        self.optimize_right = optimize_right

    def get_display_name(self) -> str:
        return self.display_name
    
    def get_description_comment(self) -> str:
        return self.description_comment

    def get_code(self) -> Tuple[List[str], List[str]]:
        return [], []

    def combine_right(self, other_code_chunk: CodeChunk) -> Optional[CodeChunk]:
        if not self.optimize_right:
            return None
        
        # We just return the other code chunk, while also updating the prev_state. To avoid
        # causing issues by modifying data, we make a copy of this object
        new_other_code_chunk = deepcopy(other_code_chunk)
        new_other_code_chunk.prev_state = self.prev_state
        return new_other_code_chunk
    
    def can_be_reordered_with(self, code_chunk: CodeChunk) -> bool:
        """
        An empty code chunk should not ever be reordered, because then it might
        take a prev_state to a place where it does not belong. 

        For example:
        1. Import CSV
        2. Delete some columns
        3. Graph it (generates EmptyCodeChunk)

        But if the EmptyCodeChunks ends up BEFORE the delete, then the delete will
        fail -- as the prev_state it has been optimized to have (from the EmptyCodeChunk)
        will not have the columns that it is trying to delete.

        So, we just return False here, to make sure that EmptyCodeChunks are never
        reordered.
        """
        return False