#!/usr/bin/env python3
# encoding: utf-8
# Copyright 2020 Huawei Technologies Co., Ltd
#
# 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.
# ============================================================================
import sys
import math

MIN_CHARS_PER_ROW = 20      # minimal number of chars on one line
COLS_TO_ROWS_RATIO = 4      # ratio of # columns to # rows (unit is char)
MAX_LABEL_LENGTH = 1000     # maximal number of chars of a label


# for specified number of chars, calculate a suitable number for how many chars per row
# Num Total Chars   : n
# Num Chars Per Row : m
# Num Rows          : k
# (k - 1) * m < n <= k * m
# suppose: m / k = u
# ==> sqrt(u * n) <= m < u / 2 + sqrt(u * n + u * u / 4)
#     m = max(20, m)
# parameters:
# @total_chars  number of total chars
# @ratio        ratio of # columns to # rows (unit is char)
def calc_num_chars_per_row(total_chars, ratio):
    chars_per_row = math.ceil(math.sqrt(total_chars * ratio))
    return max(MIN_CHARS_PER_ROW, chars_per_row)


def process_label_text(text):
    label_len = min(len(text), MAX_LABEL_LENGTH)
    chars_per_row = calc_num_chars_per_row(label_len, COLS_TO_ROWS_RATIO)
    if label_len <= MIN_CHARS_PER_ROW:
        return text
    beg_idx = 0
    texts = []
    while beg_idx < label_len:
        end_idx = beg_idx + chars_per_row
        if end_idx >= label_len:
            texts.append(text[beg_idx:label_len])
        else:
            texts.append(text[beg_idx:end_idx])
        beg_idx = end_idx
    return "\\n".join(texts)


# insert '\n' to labels which are too long
def process_file(f):
    line_text = f.readline()
    beg_idx = -1    # label begin index, index of 'label="'
    end_idx = -1    # label end index, index of '"'
    label_text = ""
    label_prefix = ""
    label_postfix = ""
    while line_text:
        line_text = line_text.rstrip()

        if beg_idx < 0:
            beg_idx = line_text.find('label="')
            if beg_idx >= 0:
                end_idx = line_text.find('"', beg_idx + len('label="'))
                if end_idx >= 0:    # the full label text is on one line
                    label = line_text[beg_idx + len('label="'):end_idx]
                    print('%slabel="%s"%s' % (line_text[0:beg_idx], process_label_text(label), line_text[end_idx + 1:]))
                    beg_idx = -1    # reset to initial conditions
                else:               # the label text is distributed on multiple lines
                    label_prefix = line_text[0:beg_idx]
                    label_text = line_text[beg_idx + len('label="'):]
            else:
                print(line_text)
        else:
            end_idx = line_text.find('"')
            if end_idx >= 0:
                label_text = label_text + line_text[0:end_idx]
                label_postfix = line_text[end_idx + 1:]
                print('%slabel="%s"%s' % (label_prefix, process_label_text(label_text), label_postfix))
                beg_idx = -1  # reset to initial conditions
            else:
                label_text += line_text

        # print(f'{len(line_text)} - {line_text}')
        line_text = f.readline()


if __name__ == "__main__":
    if len(sys.argv) > 1 and sys.argv[1] == "--help":
        print("Usage: %s < dotfile | dot -Tpng -o filename.png" % sys.argv[0])
        sys.exit()

    # read text from stdin
    process_file(sys.stdin)
