/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package tech.tablesaw.columns.booleans;

import tech.tablesaw.api.BooleanColumn;
import tech.tablesaw.columns.Column;
import tech.tablesaw.selection.Selection;

/** An interface for mapping operations unique to Boolean columns */
public interface BooleanMapUtils extends Column<Boolean> {

  /*
   * Returns a Boolean column made by and-ing this column with the arguments
   */
  default BooleanColumn and(BooleanColumn... columns) {
    String name = name() + " and: ";
    Selection selection = asSelection();
    for (BooleanColumn column : columns) {
      if (!column.name().equals(columns[0].name())) {
        name += ", ";
      }
      name += column.name();
      selection.and(column.asSelection());
    }
    return BooleanColumn.create(name, selection, size());
  }

  default BooleanColumn or(BooleanColumn... columns) {
    String name = name() + " or: ";
    Selection selection = asSelection();
    for (BooleanColumn column : columns) {
      if (!column.name().equals(columns[0].name())) {
        name += ", ";
      }
      name += column.name();
      selection.or(column.asSelection());
    }
    return BooleanColumn.create(name, selection, size());
  }

  /**
   * Returns a column made by combining the receiver and each of the arguments using the operation:
   * A andNot V. For example, the value of a cell in the result column would be true if the
   * corresponding value in A is true and the corresponding value in B is false
   */
  default BooleanColumn andNot(BooleanColumn... columns) {
    String name = name() + " and not: ";
    Selection selection = asSelection();
    for (BooleanColumn column : columns) {
      if (!column.name().equals(columns[0].name())) {
        name += ", ";
      }
      name += column.name();
      selection.andNot(column.asSelection());
    }
    return BooleanColumn.create(name, selection, size());
  }

  Selection asSelection();
}

@@ -992,32 +992,39 @@
 ns) %7B%0A    String
+Builder
  name = name() +
@@ -1020,24 +1020,48 @@
  = n
-ame() + 
+ew StringBuilder(name()).append(
 %22 and: %22
 ;%0A  
@@ -1056,16 +1056,17 @@
 %22 and: %22
+)
 ;%0A    Se
@@ -1205,32 +1205,37 @@
         name
- += 
+.append(
 %22, %22
+)
 ;%0A      %7D%0A  
@@ -1234,36 +1234,40 @@
     %7D%0A      name
- += 
+.append(
 column.name();%0A 
@@ -1255,32 +1255,33 @@
 nd(column.name()
+)
 ;%0A      selectio
@@ -1343,32 +1343,43 @@
 lumn.create(name
+.toString()
 , selection, siz
@@ -1446,32 +1446,39 @@
 ns) %7B%0A    String
+Builder
  name = name() +
@@ -1474,23 +1474,48 @@
  = n
-ame() + 
+ew StringBuilder(name()).append(
 %22 or: %22
+)
 ;%0A  
@@ -1658,32 +1658,37 @@
         name
- += 
+.append(
 %22, %22
+)
 ;%0A      %7D%0A  
@@ -1687,36 +1687,40 @@
     %7D%0A      name
- += 
+.append(
 column.name();%0A 
@@ -1708,32 +1708,33 @@
 nd(column.name()
+)
 ;%0A      selectio
@@ -1795,32 +1795,43 @@
 lumn.create(name
+.toString()
 , selection, siz
@@ -2194,16 +2194,23 @@
   String
+Builder
  name = 
@@ -2214,16 +2214,40 @@
  = n
-ame() + 
+ew StringBuilder(name()).append(
 %22 an
@@ -2254,16 +2254,17 @@
 d not: %22
+)
 ;%0A    Se
@@ -2411,16 +2411,21 @@
 name
- += 
+.append(
 %22, %22
+)
 ;%0A  
@@ -2444,12 +2444,16 @@
 name
- += 
+.append(
 colu
@@ -2461,16 +2461,17 @@
 n.name()
+)
 ;%0A      
@@ -2552,16 +2552,27 @@
 ate(name
+.toString()
 , select

Use StringBuilder